-
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.
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
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
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.
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).
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)
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)
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 filesgit 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 !
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
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.
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
Once all is tested, reviewed, corrected and validated, your work is merged.
Good job, everything is fine. You can start a new feature.
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.
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
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)
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
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)