Skip to content

Instantly share code, notes, and snippets.

@arhgi128
Last active November 16, 2023 09:51
Show Gist options
  • Save arhgi128/63b77e09073660d84d7a2e66bf3d52b7 to your computer and use it in GitHub Desktop.
Save arhgi128/63b77e09073660d84d7a2e66bf3d52b7 to your computer and use it in GitHub Desktop.
Git basic workflow guide

Git basic workflow guide

I. Disclaimers

  • This guide is more a cheat sheet on a type of git workflow than a tuto. If you need to learn git, there are many tutos and trainings available. There are also many more complete git commands cheat sheets available.

  • It has been kept quite simple to be just a good base and you will come to more complex operations as your work and knowledge goes on.

  • This guide is based on the process I have used on the projects I have been working on and this gives a solid versionning process base. But the process that are used on your project may differ. Please follow your team guidelines first.


II. Git configuration

Set the name that will be attached to your commits and tags.

git config --global user.name “Your Name”

Set the e-mail address that will be attached to your commits and tags.

git config --global user.email “you@example.com”

Enable some colorization of Git output.

git config --global color.ui auto

(thanks to @gafou who gave me the following)

Add an alias for a git log command with graph and color

git config --global alias.lg4 "log --color --graph --pretty=format:'%C(bold red)%h%Creset -%C(bold yellow)%d%Creset %s %C(bold green)(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

Note : you can also do all this by editing ~/.gitconfig.

[user]
  name = Your Name
  email = you@example.com
[color]
  ui = auto
[alias]
  log --color --graph --pretty=format:'%C(bold red)%h%Creset -%C(bold yellow)%d%Creset %s %C(bold green)(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

1. Display git branch and status in bash directory

This uses git-prompt.sh which is normally installed as it is provided by git.

Add the following in ~/.bashrc:

# display unstaged (*) and staged (+) changes
GIT_PS1_SHOWDIRTYSTATE=1
# display if something is stashed ($)
GIT_PS1_SHOWSTASHSTATE=1
# display if there untracked files (%)
GIT_PS1_SHOWUNTRACKEDFILES=1
# display differences between local and origin (<, >, <>, =)
GIT_PS1_SHOWUPSTREAM="auto"

# Add git branch name to directory
if [ "$color_prompt" = yes ]; then
#    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
     PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[01;34m\]\w\[\033[1;33m\]$(__git_ps1)\[\033[00m\]\$ '
else
#    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$(__git_ps1)\$ '
fi

III. Starting A Project

Create a new local repository.

git init [project name]

If [project name] is provided, Git will create a new directory name [project name] and will initialize a repository inside it. If [project name] is not provided, then a new repository is initialized in the current directory.


IV. Working on a project

1. Start a new feature / bugfix ...

Go to your start branch (generally develop but can be different, in case of hotfix for example).

git checkout develop

Fetch and pull the last version.

git pull

Create a new branch for your work and switch to it.

git checkout -b branch_name

(equivalent to git branch branch_name and git checkout branch_name). Your branch name must be explicit and generally follows requirements defined in your project team. (ex : feature_1234_add_feature_xxx_to_process_yyyy).

2. Every day work

After a feature step is done or when you need to "save" your work, do a commit:

View the status of your working directory

git status  

And verify only files you have modified are present (ex: do not commit csv files copies that are opened with LO calc or MS Excel).

Add files to the index

git add XXX  

Where XXX are the files / directories to be commited (use git add . only if you are sure of what you are doing and you have well verified the list of files).

Commit your work

git commit

And in the editor enter the details of your work, then save and quit. If not much detail is needed (ex: if you are commiting to save your work at the end of the day), use git commit -m "commit message".

Push your commited work to remote.

git push (origin branch-name)

3. when your feature is finished

Tip : When to merge and when to rebase

Basically: merge takes the commits of the other branch and adds it on top of the current branch, whereas rebase is pulling the latest state of other branch and replay your branch on top of it.

The rules:

  • Do not merge develop (or your base branch) on your branch : rebase your branch on develop
  • Do not rebase develop (or other base branch as main/master) : merge into it. (thanks @rocha)

3.1. Clear your history

You do not have to keep all your commits, especially the "work in progress" commits. So you have to clean your commits by squashing them

View your history with all the commits.

git log

Squash your commits.

git rebase -i HEAD~n (where n is the number of commits to be squashed)

In the first text editor, use pick for commits to be kept (at least the first one), s for commits to be squashed with previous one. Then save and quit. In second editor, review you final commit message. Then save and quit.

It is possible that you have some conflicts during this process. In this case :

  • edit each conflicting file using a merge/diff tool and keep the work that needs to be kept, then save.
  • git add XXX to add modified files
  • git rebase --continue

Push the squashed commit to server.

git push --force-with-lease

As you push modification of an existing commit, you have to force the push. The "with lease" avoid pushing your code if the target branch is not at the same commit as your base commit.

! NEVER use git --force if you are not a git expert AND you are sure what your are doing !

3.2. Rebase your work

If your base branch (develop) has evolved following on merge of other features, you need to rebase your work on it.

Pull last version of develop and replay your commits on it.

git pull --rebase origin develop

(Note this is easier if you have already done the squashing.)

If conflicts occur, use same conflicts resolution process as for squashing.

Push your rebased commit to the server.

git push --force-with-lease

3.3. Create your merge request

Go to your git remote interface (github, gitlab ...) and create your merge request and submit it for review to your colleagues once everything is tested.

3.4. if you need to add some code to your final (squashed) commit

For example to push corrections and modifications following on tests or code review comments.

You can create a new commit and squash again when ok.

Or you can update your commit:

git status
git add XXX
git commit --amend --no-edit

The last line amends (updates) your commit with added modifications without modifying the commit message. (If you need to edit the commit message use only git commit --amend) (note that, if you need to modify your commit message, you can do it using git commit --amend even if you have not modified your code)

Push your updated commit.

git push --force-with-lease

3.5. Your worked is merged

Once all is tested, reviewed, corrected and validated, your work is merged.

Good job, everything is fine. You can start a new feature.


V. Emergency

You have forgotten to pull last version before working, you did the wrong git command, you're git history is messed up and you can't do anything to solve it ? Here are a few tips that may help you.

1. Stash your work

Stashing allows to put on hold your not committed work and retrieve initial state.

Add not followed files if you want to stash them (not necessary)

git add .

Put your uncommitted files appart

git stash

When you want, retrieve last stashed code.

git stash pop

2. Reset your work

Git offers different levels of reset

Cancel all non added modifications

git checkout -- .

Cancel non committed modifications

git reset HEAD .

Cancel last N commits but keep the work as not added

git reset --soft HEAD~N

Cancel all modifications even if committed

git reset --hard [point]

Reset to HEAD state if no "point" is entered or to the "point" state. "point" can be a commit or a branch from your history (git reset --hard origin/develop will reset to develop state)

3. Delete local work and retrieve server version

Go back to develop.

git checkout develop

Delete the branch on local.

git branch -D branchname

Go back to branchname in server state.

git checkout branchname

4. Move your work to a new branch to squash your commits

You're having too much troubles squashing your commits into a single one ? Move your work to a new branch easily using git diff and git apply.

Note : for this specific case, we cannot use git format-patch and git am because they include the commits and we don't want to keep them.

Do a patch file from a diff

git diff develop my-branch > my_branch_diff.patch

Create your new branch

git checkout develop
git checkout -b my_new_branch

Apply the patch

git apply my_branch_diff.patch

Create your new commit

git commit

Author : Raphaël Glavieux Copyright : Creative Commons SA (Share Alike)


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment