Skip to content

[git] Tips

Infernio edited this page Apr 18, 2021 · 45 revisions

The commands are typed in the msysgit Bash window.

  • pull.ff only

      git config --global pull.ff only
    

    That way you will never get bogus merge commits from git pull. Turns a timebomb into a nice shortcut.

  • List files:

      git ls-tree -r dev --name-only
    
  • Enable git rerere (stands for reuse recorded resolution):

      git config --global rerere.enabled true
    

    This will remember the resolution you made for a conflict and reapply it when you perform an identical rebase. If you recorded one wrong resolution you can always forget it.

  • git config merge.conflictStyle diff3

    Shows the common ancestor as well when displaying a merge conflict. Why this isn't the default, I don't know.

      <<<<<<< HEAD
      	MelDecalData, MelDescription
      ||||||| parent of 341db5357... Deduplicate ETYP subrecords
      	MelDescription
      =======
      	MelDescription, MelLists
      >>>>>>> 341db5357... Deduplicate ETYP subrecords
    
  • git reflog

    Git keeps unreachable objects around for a while and lists the SHAs of all recent objects that you worked on here. If you accidentally hard-reset, fetch-prune, etc. some important work, you can recover it using these SHAs. Learn it and love it. It will save your life one day :)

  • Compare two commits in gitk

    gitk compare commits

  • Set up an editor for git Bash (unless you're fine with vim of course ;))

    Do it! It is essential to use git rebase and if you can't use vim you won't be able. Essentially you just need to issue :

      git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
    

    (for Notepad++ for instance) but see here for latest updates and more flexible ways.

  • Listing people who contributed to a release

    Since git 2.29, you can finally handle Co-authored-by as well:

    $ git shortlog -ns --group=author --group=trailer:signed-off-by v307..v308
     258  Infernio
     145  MrD
      10  Daniel Nunes
       4  lojack5
       1  Kenneth M. Glassey
       1  LordNyriox
       1  Luna
       1  valda
    
  • Show all changed files between two commits

    git diff --name-only SHA1 SHA2

    If you want also to see the status (modified, deleted, added)

    git diff --name-status SHA1 SHA2

    And to see lines added or deleted

    git diff --stat SHA1 SHA2 the SHAs can actually be branch names as in git diff --stat master dev

    Bonus: Exclude a directory from git diff:

    git diff --stat dev -- . ':!/Mopy/Docs/*'

  • Copying commit information

    I had to merge an old pull request - after I created a merge commit (with parents the dev branch and the pull request commit) I issued:

    git cherry-pick -m 1 <sha-of-merge-commit> # on dev
    # `-m 1` specifies parent dev commit
    

    to cherry pick the merge commit on dev . However, the merge commit had me as the author. Fix:

    git commit -C <sha-of-pull-request-commit> --amend # on dev
    
  • Excluding files locally

    You may want to exclude files or directories locally - use the .git/info/exclude file. It has exactly the same syntax as the .gitignore file and comes very handy when you have files you want to exclude locally. You can copy paste the filename from git gui as above (where the file will appear as untracked) and issue:

       echo "junk filename with spaces" >> .git/info/exclude
    
  • Recovering from a (mild) upstream rebase

    I had to recover from an upstream rebase (the #78) and I hadn't done this before. git pull by default force updates the local refs to the remote branches.

      Welcome to Git (version 1.8.5.2-preview20131230)
    
      $ git pull
      # ...
       + ca25062...b62b479 dev        -> origin/dev  (forced update)
      # ...
    

    I had to manually reset my local tracking branches to the remote ones - I did it conveniently in gitk. In the process I realized that I had a lot of stale remote branches - to clear them:

  • Clear (aka prune) deleted remote branches
     $ git remote prune origin --dry-run
     Pruning origin
     URL: git@github.com:wrye-bash/wrye-bash.git
      * [would prune] origin/lojack-fix-bug-87
      * [would prune] origin/lojack-fix-bug-91
      * [would prune] origin/lojack-fix-bug-98
    

    --dry-run is always a good idea - omit it and go for it. Other solutions described here - git branch -rd origin/branchname would come handy.
    In most cases git pull --prune would suffice.
    To actually delete a remote branch (in github) use git push origin --delete <branchName>

  • Alias for running gitk & git gui at once

    If you find yourself using gitk and git gui commands a lot (you should!) here is an alias you could use (in your ~/.gitconfig file):

     [alias]
     	gg = !sh -c ": ; (gitk --all &) ; (git gui &)"
    
  • Alias for running notepad++ right from git Bash

    You should add this to your "C:\Users\User\.bash_profile":

     alias npp="/c/Program files (x86)/Notepad++/notepad++.exe"
    

    That's all - now you can easily $ npp path/to/file from the git Bash shell. Notice you can easily copy the path to the file from git gui: ![git gui copy filename](images/git gui copy filename.jpg)

  • Lola

    I do recommend gitk --all & for viewing the tree but for the shell crowd there is lola. Just copy the following into ~/.gitconfig for your full color git lola action:

      [alias]
      		lol = log --graph --decorate --pretty=oneline --abbrev-commit
      		lola = log --graph --decorate --pretty=oneline --abbrev-commit --all
      [color]
      		branch = auto
      		diff = auto
      		interactive = auto
      		status = auto
    
  • A handy way to delete all .pyc files from the git-bash command line:

       `find . -name "*.pyc" -delete`
    
  • Github Secrets No-Whitespace view is a useful thing to keep in mind if your pet-peev relates to whitespace. Just tack ?w=1 to the URL in github and have whitespace only diffs omitted from the view.

  • Find any file deleted in any commit in the tree:

       git log --diff-filter=D --summary | grep "delete mode 100" | cut -c 21- | sort > deleted.txt
    
  • Create a branch from git stash

      $ git stash branch testchanges
    
  • Advanced: Git interactive rebase: instruct git to resolve conflicts keeping the HEAD version. As torek the great comments dump the cryptic script from the linked answer:

     git ls-files -u | cut -f2- | uniq | git checkout-index --stdin --stage=all \
     | while read base ours theirs path; do
             git merge-file --ours \
                     -L "$path" -L o/"$path" -L b/"$path" \
                     -- $ours $base $theirs
             mv $ours "$path"
             rm $base $theirs
     done
    

    run git rebase -i, and whenever it stops with conflicts, run the script. Very handy to quickly resolve conflicts from a branch that failed out of sync with upstream


Clone this wiki locally