GitHub Logo

global info

git remote -v
git branch -v

Git Config

Basic config

git config --global "John Doe"
git config --global

Write config in ~/.gitconfig

Custom email depending on repositories clone path

requires git 2.13
If you share your workstation between profesional and personal project, you might want to select from which username and email you commit (+ optionaly you sign-off).

cat ~/.gitconfig

  name = Baptiste Dauphin
    gpgsign = true
[includeIf "gitdir:~/Git/company/**"]
  path = ~/.gitconfig-company
[includeIf "gitdir:~/Git/personal/**"]
  path = ~/.gitconfig-personal
  editor = subl -n -w
cat ~/.gitconfig-company

email = *********
signingkey = ***************************
cat ~/.gitconfig-personal

email =
signingkey = 5A040187EDDDD936B41E8268E4577920E02746B3

Test at run time

When you commit, git will concatenate all data from :

  • .git/config (repository-wide config)
  • ~/.gitconfig (user-wide config)

To test

git config --get-all
git config --get-all

git config --get-all user.signingkey
git config --get-all commit.gpgsign

git config --get-all core.editor

Git add

Add a file to the index.
The inverse command is git reset.

git add file

Let's you select only a hunk of the file.
i.e. add just a part of the file
Interactive mode :)

git add --patch file
Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?`

Here is a description of each option:

  • y stage this hunk for the next commit
  • n do not stage this hunk for the next commit
  • q quit; do not stage this hunk or any of the remaining hunks
  • a stage this hunk and all later hunks in the file
  • d do not stage this hunk or any of the later hunks in the file
  • g select a hunk to go to
  • / search for a hunk matching the given regex
  • j leave this hunk undecided, see next undecided hunk
  • J leave this hunk undecided, see next hunk
  • k leave this hunk undecided, see previous undecided hunk
  • K leave this hunk undecided, see previous hunk
  • s split the current hunk into smaller hunks
  • e manually edit the current hunk
  • ? print hunk help

The inverse command of git add is git reset.


Track as early as possible

This means that you should tell LFS to track a file before it's committed to the repository.

Otherwise, it has become part of your project's history - including all of its megabytes and gigabytes…

git lfs track "design-resources/design.psd"

See pattern matching (not listing files).

cat .gitattributes
design-resources/design.psd filter=lfs diff=lfs merge=lfs -text

Tracking file patterns

git lfs track "*.indd"
git lfs track "design-assets/*"

Getting an overview of tracked files

git lfs ls-files
194dcdb603 * design-resources/design.psd

Official doc

Git Reset

The git reset command is a complex and versatile tool for undoing changes. It has three primary forms of invocation. These forms correspond to command line arguments --soft, --mixed, --hard. The three arguments each correspond to Git's three internal state management mechanism's, The Commit Tree (HEAD), The Staging Index, and The Working Directory.

Git reset & three trees of Git

To properly understand git reset usage, we must first understand Git's internal state management systems. Sometimes these mechanisms are called Git's "three trees".

GitHub Logo

Undo a commit and redo

git commit ...
git reset --soft HEAD^
git commit -a -c ORIG_HEAD

Git rm

If you are simply not interested in this file anymore, you can use the “git rm” command in order to delete the file from the index (also called the staging area).

git rm --cached <file>

When you are done with the modifications, you can simply commit your changes again with the “–amend” option.

git commit --amend

To verify that the files were correctly removed from the repository, you can run the “git ls-files” command and check that the file does not appear in the file (if it was a new one of course)

git ls-files


Git remote

Edit remote URL

git remote set-url origin

Git Tag

create tag at your current commit

git tag temp_tag_2

By default tags are not pushed, nor pulled

git push origin tag_1 tag_2

list tag

git tag -l

delete tag

git tag -d temp_tag_2

Get the current tag

git describe --tags --exact-match HEAD

Git Checkout

You can checkout at either a branch, a tag or a commit

git checkout dev
git checkout master
git checkout branch
git checkout v_0.9
git checkout ac92da0124997377a3ee30f3159cdee838bd5b0b

Give up all your modifications (i.e. git checkout all the files)

git checkout -- .

Git Branch

Get the current branch name

git branch | grep \* | cut -d ' ' -f2

Git pull

git pull

Want to go one step earlier (just before git pull ?)

git reset --keep HEAD@{1}

This works because it's the last action on your reference log ;) Check it out :

git reflog show

Git push

git push

Prévient si tu vas écraser des commits créés entretemps par quelqu'un.
Si tu travailles dans un même branch avec d'autres c'est pratique.

git push --force-with-lease

Git Diff

Specific file

git diff -- human/

Global diff between your unstagged changes (workspace) and the index

git diff

Global diff between your stagged changes (index) and local repository

git diff --staged

See what will be pushed

git diff --stat --cached origin/master
git diff master@{} master@{0}

Git Stash

Extract your work from the index and workspace.

git stash save

And put your work back !

git stash pop

To list the stashed modifications

git stash list

To show files changed in the last stash

git stash show

To view the content of an arbitrary stash, run something like

git stash show -p stash@{1}

Git merge

git pull = git fetch && git merge

Merge conflicts

In case of conflict when pulling, by default git will conserve both version of file(s)

git pull origin master

git status

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)
Unmerged paths:
  (use "git add <file>..." to mark resolution)

  both modified:   path/to/file

keep the local file or the remote file during merge (conflict)

git checkout --theirs /path/to/file

git checkout --ours /path/to/file

Undo/move your work

with Git reset and Git stash go at the previous commit. will uncommit your last changes

git reset --soft HEAD^

hide temporary your work in a dirty magic directory and verify the content of it

git stash
git stash show

Try to FF merge without any conflict

git pull

put back your work by spawning back your modifications

git stash pop

And then commit again

git commit "copy-paste history commit message :)"

Override a given side by another

You can tell him that you want your modifications take precedance So, in that case of merge conflict cancel your conflict by cancel the current merge,

git merge --abort

Then, pull again telling git to keep YOUR local changes

git pull -X ours origin master

Or if you want to keep only the REMOTE work

git pull -X theirs origin master

Git ls-tree

How to retrieve the last modification date of all files in a git repository ?

git ls-tree -r --name-only HEAD | while read filename; do
  echo "$(git log -1 --format="%ad" -- $filename) $filename"

Git Log

Find commit by author or since a specific date

git log --author="b.dauphin" \
    --since="2 week ago"

Find n last commit

git log --author="b.dauphin" \

only print specific info from commits

git log --since="2 week ago" \

hash, author name, date, message

git log --author="b.dauphin"  \
    --since="2 week ago" \
    --pretty=format:"%h - %an, %ar : %s"

Show modification of specific commits

git show 01624bc338d4a89c09ba2915ff25ce08174b8e93 3d9228fa99eab6c208590df91eb2af05daad8b40

See changes to a specific file using git

git log --follow -p -- file
git --no-pager log --follow -p -- file

See commit Signature (GPG)

git log --show-signature

Git Reflog

git reflog show INFRA-5993@{0}
git reflog show master@{0}

Git Shortlog

Qui a le plus commit ? i.e. qui a la plus grosse ?

git shortlog -s -n --all


Git Revert

The git revert command can be considered an 'undo' type command, however, it is not a traditional undo operation. INSTEAD OF REMOVING the commit from the project history, it figures out how to invert the changes introduced by the commit and appends a new commit with the resulting INVERSE CONTENT. This prevents Git from losing history, which is important for the integrity of your revision history and for reliable collaboration.

Reverting should be used when you want to apply the inverse of a commit from your project history. This can be useful, for example, if you’re tracking down a bug and find that it was introduced by a single commit. Instead of manually going in, fixing it, and committing a new snapshot, you can use git revert to automatically do all of this for you.

GitHub Logo

git revert <commit hash>
git revert c6c94d459b4e1ed81d523d53ef81b6a4744eac12

find a specific commit

git log --pretty=format:"%h - %an, %ar : %s"

Git Cherry-pick

I have 2 branches, master and dev.
I am on dev branch and I want to cherry-pick 1 commit from master to dev. So I did.

git cherry-pick 125842ac1228c2a2c37b3be4a5ab7681e648a7fb

In case of conflicts it's still possible to keep theirs or ours modifications

git cherry-pick 125842ac1228c2a2c37b3be4a5ab7681e648a7fb -X ours
git cherry-pick 125842ac1228c2a2c37b3be4a5ab7681e648a7fb -X theirs

Git Blame

See who last edited each lines of file.

git blame file

Git Bisect

Helps you to find the commit that introduced a bug by dicotomy or bisection.

division of something into two equal, usually by a line, which is then called a bisector.

The idea behind git bisect is to perform a binary search in the history to find a particular regression. Imagine that you have the following development history:

... --- 0 --- 1 --- 2 --- 3 --- 4 --- 5 --- current

You know that your program is not working properly at the current revision, and that it was working at the revision 0. So the regression was likely introduced in one of the commits 1, 2, 3, 4, 5, current.

You could try to check out each commit, build it, check if the regression is present or not. If there is a large number of commits, this can take a long time. This is a linear search. We can do better by doing a binary search. This is what the git bisect command does. At each step it tries to reduce the number of revisions that are potentially bad by half.

You'll use the command like this:

git stash save
git bisect start
git bisect bad
git bisect good 0
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[< ... sha ... >] 3

After this command, git will checkout a commit. In our case, it'll be commit 3. You need to build your program, and check whether or not the regression is present. You'll also need to tell git the status of this revision with either git bisect bad if the regression is present, or git bisect good if it is not.

Let's suppose that the regression was introduced in commit 4. Then the regression is not present in this revision, and we tell it to git.

make test
... ... ...
git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[< ... sha ... >] 5

It will then checkout another commit. Either 4 or 5 (as there are only two commits). Let's suppose it picked 5. After a build we test the program and see that the regression is present. We then tell it to git:

make test
... ... ...
git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[< ... sha ... >] 4

We test the last revision, 4. And since it is the one that introduced the regression, we tell it to git:

make test
... ... ...
git bisect bad
< ... sha ... > is the first bad commit
< ... commit message ... >

In this simple situation, we only had to test 3 versions (3, 4, 5) instead of 4 (1, 2, 3, 4). This is a small win, but this is because our history is so small. If the search range is of N commits, we should expect to test 1 + log2 N commits with git bisect instead of roughly N / 2 commits with a linear search.

Once you've found the commit that introduced the regression, you can study it to find the issue. Once this is done, you use git bisect reset to put everything back on the original state before using git bisect command.


First time

First time, clone a repo including its submodules

git clone --recurse-submodules \
-j8 \

Daily usage

Update an existing local repositories after adding submodules or updating them

git pull --recurse-submodules
git submodule update --init --recursive

Remove a submodule you need to:

  • Delete the relevant section from the .gitmodules file
  • Stage the .gitmodules changes git add .gitmodules
  • Delete the relevant section from .git/config
  • Run git rm --cached path_to_submodule (no trailing slash)
  • Run rm -rf .git/modules/path_to_submodule (no trailing slash).
  • Commit git commit -m "Removed submodule"
  • Delete the now untracked submodule files rm -rf path_to_submodule

Install specific version

Check the latest not-release-candidate, so a stable version, on the mirror on github

apt install make libssl-dev libghc-zlib-dev libcurl4-gnutls-dev libexpat1-dev gettext unzip
git clone
cd git
git checkout v2.13.7
sudo apt remove git
whereis git
make prefix=/usr/local all -j$(grep -c ^processor /proc/cpuinfo)
sudo make prefix=/usr/local install -j$(grep -c ^processor /proc/cpuinfo)
git --version

results matching ""

    No results matching ""

    results matching ""

      No results matching ""