git recipes
Over time I've been collecting command snippets for doing various things. These might be some simple things but not necessarily something that I do every day. This way I don't need to remember them after a few weeks or moths, nor figure them out nor find them on the Internet every time, I just copy-paste them from my recipes collection. Various people who have seen my collection have asked for a copy. So I've figured that I can as well share them in general, they will be here under the tag recipes (and I've already had a post about the clustering commands tagged with it).
This installment is about git:
# Git book
https://progit.org/
# Basic Git
https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository
# Git Branches
https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell
# working with remote repositories
https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes
# set the editor
set GIT_EDITOR=gvim
# create the git repo and initial commit for an existing code base
cd myproject
git init --separate-git-dir=c:\git\myproject
git add .
git commit -a
# to restore the .git file pointing to a separate dir, put in it:
gitdir: c:/git/myproject
# To move the work tree, edit c:\git\myproject\config and change the worktree
# location there.
# in push and pull USE THE WORKING DIRECTORY, not the separate git dir!!!
# show the location of the remote branches (origin)
git remote -v
# show how the local and remote branches are connected
git remote show origin
# set the push mode to push only the current branch
git config push.default simple
# set the mode to push all the branches to the matching ones
git config push.default matching
# set to use the access token
# Set up a Personal Access Token (PAS) in VSO https://project.visualstudio.com/_details/security/tokens (much like github with 2FA)
git config credential.https://project.visualstudio.com.username me@domain.com
git config credential.https://project.visualstudio.com.helper store
# then do "git remote show origin" and enter the password once manually,
# it will be stored in ~\.git-credentials
# Or enter the line there manually, like:
https://me%40domain.com:TextOfTheAccessToken@project.visualstudio.com
# to see all branches, including the ones that were pulled but not checked out
git branch -a
# to undo a merge
git reset --hard <last_old_change>
# to merge one change
git cherry-pick <change_id>
# to remember the conflict resolutions from cherrypicking, when cherrypicking
# to multiple branches
git config --global rerere.enabled true
# control the rerere cache
git rerere
# show the messages of last commits of every branch
git branch -vv
# merge a difference between 2 branches onto the 3rd one:
# pick the changes that are on client but not on server branch and copy them to the master branch
git rebase --onto master server client
# Show the list of commits differing between two branches - what is present on origin/master but missing on issue54
git log --no-merges issue54..origin/master
# Show the list of commits on branch "contrib" since the branch was started off master
git log contrib --not master
# find the base commit on which the branch "contrib" started off "master"
git merge-base contrib master
# show the diff since the branch "contrib" was started off "master"
# https://git-scm.com/book/en/v2/Distributed-Git-Maintaining-a-Project
git diff master...contrib
# Cloning a repository:
cd c:\work
git clone -l --separate-git-dir c:\git\myproject2 --no-hardlinks c:\work\myproject myproject2
# "git pull" is a combination of "git fetch" and "git merge"
git pull origin # or just git pull
# the safer option that keeps moving the local commits to the end of the chain is
git pull --rebase
# (the downside is that it can create a whole lot of merge conflict pain?)
# or to make this behavior default set
git config --global pull.rebase true
# push one branch to origin, creating it there
# -u sets the upstream connection between the branches
git push -u origin featureA
git push --set-upstream origin nano_pr
# Push a local branch to a differently named remote branch (refspec)
# local featureB to origin/featureBee
# -u sets the upstream connection between the branches
git push -u origin featureB:featureBee
# Create a branch off an origin branch
git fetch origin
git checkout -b featureB origin/master
# Merge a branch, squashing all its commits into one commit (and losing the
# proper connection to that branch, so it's dangerous; after that you couldn't
# merge from master to featureB any more, and the branch featureB becomes
# essentially dead)
git merge --squash featureB
# How to merge with squashing but preserving the dependencies between branches:
# suppose we have the branch "work". Create another intermediate branch "work_pr"
# for submitting the PRs through it.
git checkout work_pr
git merge --squash work
# after that, do:
git commit -a # edit the message
git merge work # needed to record the proper merge, to not have the same changes appear the second time
git checkout work
git merge work_pr # record the proper history the other way around
git checkout work_pr
# now push work_pr and create a PR from it
# Create a patch (-M includes the renames)
git format-patch -M origin/master
# apply a patch (similar to patch -p1 but can handle renames and deletes in git patch format)
git apply /tmp/patch-ruby-client.patch
# apply a patch including the commit comments, and/or multiple patches from a mailbox file
git am 0001-limit-log-function.patch
# same but smarter, taking in account the original version
git am -3 0001-limit-log-function.patch
# Create a local branch that tracks the remote branch from origin
# (see https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches )
git checkout -b serverfix origin/serverfix
# or the same
git checkout --track origin/serverfix
# save the current state of the branch as a tar file:
git archive master --prefix='project/' | gzip > master.tgz
# see https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection
# log of recent actions
git reflog
# show the difference from the last commit
# "^" means the parent of the named commit, if multiple parents (such as in a merge),
# "^2" can be used for the second parent.
git diff "HEAD^"
# Same, but "~2" means "grandparent" etc. Can also write "^^" for grandparent, etc.
git diff HEAD~
# Show the commits done on experiment after it branched off master
git log master..experiment
# Show the commits on both branches since they diverged
git log master..experiment
# Same and also show which commit is on which branch
git log --left-right master...experiment
# remove the unstaged files
# -x includes the ignored files into cleaning
# -d removes the directories too
# -i asks interactively
git clean -f -x -d
# search through the code base, printing the line numbers
git grep -n gmtime_r
# show just the count f matches per file
git grep --count gmtime_r
# show along with the function name where the item is found, as parsed by git
git grep -p gmtime_r *.c
# other grep output options: --break, --heading
# --and looks for multiple items on the same line
# May specify a tag or branch as an argument
git grep --break --heading \
-n -e '#define' --and \( -e LINK -e BUF_MAX \) v1.8.0
# find the commit where the ZLIB_BUF_MAX was added or removed
git log -SZLIB_BUF_MAX --oneline
# find commits with changes to a particular function (as parsed from the source code)
git log -L :git_deflate_bound:zlib.c
# find commits by a regex range of changes
git log -L '/unsigned long git_deflate_bound/',/^}/:zlib.c