.. -*- coding: utf-8; -*-====== Git.======.. contents:: :local:Setting up git==============Debian:: $ sudo apt-get install gitCygwin:: $ setup.exe -p git $ apt-cyg install gitAfter install set up some options:: $ git config --global user.name "Oleksandr Gavenko" $ git config --global user.mail "gavenkoa@gmail.com"After that you should have:: $ cat ~/.gitconfig [user] name = Oleksandr Gavenko mail = gavenkoa@gmail.comgit over proxy.===============Only http:// protocol support proxy (not git://):: $ export http_proxy="http://username:password@proxy:port/" $ git clone http://github.com/$user/$proj.git $projYou can store proxy settings under repository local config file:: $ git config http.proxy http://$user:$passwd@$ip:$portStart project with git======================Setup proj space on fs:: $ mkdir proj $ cd proj $ git init Initialized empty Git repository in /home/user/tmp/proj/.git/ $ ls -a . .. .gitAdd file, make changes, commit all:: $ emacs Makefile ... C-x C-c $ emacs app.c ... C-x C-c $ git add Makefile app.c $ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: Makefile # new file: app.c #or just:: $ git add .Commit newlly added file:: $ git commit ... Write message log ... Created initial commit 2169263: My first commit massage. 1 files changed, 4 insertions(+), 0 deletions(-) create mode 100644 app.cShow difference===============Show difference between index/stage and working tree:: $ git diffShow difference between ``HEAD`` and index (what is going to be commited):: $ git diff --cached $ git diff --staged.. note:: ``--cached`` and ``--staged`` are synonyms.Show difference beetween ``HEAD`` and working tree (what is commited after ``git commit -a``):: $ git diff HEAD $ git diff HEAD -- $pathShow difference in changeset:: $ git show $hashShow difference between revisions:: $ git diff $rev1..$rev2 $ git diff ORIG_HEAD..HEADFor merge first parent is a tip where merge is performed, second is a tip of merged branch... note:: ``git show`` shows "combined diff": only files which were modified from all parents. ``git show --first-parent`` can be used to show how branch was chaged after merge.Show differences to each parent for merge:: $ git show -m $hashhttps://stackoverflow.com/questions/3293607/difference-between-git-head-and-the-current-project-state Difference between git HEAD and the current project state?https://stackoverflow.com/questions/40986518/git-show-of-a-merge-commit git show of a merge commit.Undo tracking added file.=========================You do:: $ git add badfile $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: badfile #To stop tracking badfile do:: $ git rm --cached badfile $ git status # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # file nothing added to commit but untracked files present (use "git add" to track)or:: $ git reset badfileCommitting changes==================Individual file:: $ $EDITOR Makefile $ git add Makefile $ git diff --cached $ git commit -m "..."Commit all changed and previously manages files:: $ git commit -a -m "...."Managing branches=================Print current branch:: $ git branchList all known branches:: $ git branch -aList all known remote branches:: $ git branch -rList all remote branches directly from remote:: $ git ls-remote $ git ls-remote originList registered remotes:: $ git remote -v $ git remote $ git remote showList remote branches from ``$REMOTE`` remote:: $ git ls-remote --heads $REMOTE $ git remote show $REMOTESpecial case of above is ``origin`` remote, which is default remote:: $ git remote show origin $ git ls-remote --heads origin.. note:: Look to ``[remote "..."]`` in ``~/.git/config`` to find out names of possible remotes. Alternatively get list from:: $ git remote showGetting branches pointers from default (``origin``) remote (without mergingtracking branch):: $ git fetchGetting branches pointers from ``$REMOTE`` remote:: $ git fetch $REMOTETo get updated with default remote changes:: $ git pullor specify concrete remote:: $ git pull $REMOTE $ git pull originDelete local branch (``-D`` is unsafe i.e. changes aren't pushed to any remote):: $ git branch -d $NAME $ git branch -D $NAMEDelete remote branch:: $ git push $REMOTE --delete $BRANCH_NAME $ git push $REMOTE -d $BRANCH_NAME $ git push origin -d $BRANCH_NAMETo locally remove pointers to deleted remotely branches:: $ git remote update --prune $ git remote update --prune origin.. note:: Only curtain branches fetched by default:: [remote "origin"] url = ... fetch = +refs/heads/*:refs/remotes/origin/* Edit ``fetch`` value to change defaults.Move branch pointer to arbitrary hash:: $ git branch -f $NAME $HASHCreate local branch from remote with the same name:: $ git checkout --track origin/fixCreate local branch from remote with an alternative name:: $ git checkout -b myfix origin/fixgit analog of 'hg incoming'===========================git does not directly support such feature. You can emulate it by:: $ git fetch $ git log master..origin/master # or just '..origin/master'By previous commands you grab changes from remote server! You can apply them by``pull`` or ``merge`` or ``rebase`` command:: $ git pull $ git merge TODOTo detect if remote repository have new changes:: $ git ls-remote $ git ls-remote $upstreamView git commits================Review specific commit with:: $ git show $REV $ git diff $REV^ $REVReview merge commit related to specific parent:: $ git diff $REV^1 $REV $ git diff $REV^2 $REV $ git diff HEAD^1 HEAD $ git diff HEAD^2 HEAD.. note:: ``^1`` is the first parent, ``^2`` is the second parent, and so on.``git show`` command for merge commits shows only changes from conflicting hunks. It is equivalentto (lines that changed as part of the conflict resolution):: $ git diff-tree --cc $REVReview difference between commits:: $ git $REV1 $REV2 $ git $REV1..$REV2 $ git $REV1..$REV2 -- $DIR_OR_FILEReview history with diffs:: $ git log -p $ git log -p $FROM_REVReview history of merges only:: $ git log --min-parents=2 -p --ccView unpublished git commits / analog of git 'hg outgoing'==========================================================``git`` does not directly support such feature. Recently ``hg`` start trackingchanges that pushed to any other repositories (called as ``public`` versus``draft`` which is not yet published anywhere). You can emulate it by:: $ git fetch origin $ git log origin/master..master $ git log origin/master.. $ git log origin/master..HEAD $ git log @{u}.. $ git diff origin/master..Verbose syntax:: $ git log --branches --not --remoteshttp://stackoverflow.com/questions/2016901/viewing-unpushed-git-commits Viewing unpushed Git commits.http://stackoverflow.com/questions/3636914/how-can-i-see-what-i-am-about-to-push-with-git How can I see what I am about to push with git?git analog of 'hg glog'=======================:: $ git log --all --graph $ git log --all --graph --oneline $ git log --all --graph --oneline --decorateAdd alias:: [alias] glog = log --all --graphGit analog of 'hg rollback'===========================To edit commit message of last commit:: $ git commit --amend -m "$MSG"To integrate changes into last commit (``-a`` to avoid antecedent ``git add ...``,``--no-edit`` if you don't like to change commit message, otherwise externaleditor is opened):: $ git commit -a --amend --no-editTo edit messages of old commits starting from ``$REV``:: $ git rebase -i $REVTo undo latest commit:: $ git reset HEAD~1Git analog of 'hg root'=======================:: $ git rev-parse --show-toplevelMaking local branch tracking remote===================================:: $ git branch -u upstream/foo $ git branch -u upstream/foo foo $ git branch --set-upstream-to=upstream/foo $ git branch --set-upstream-to=upstream/foo fooShowing what and how local branches are tracked:: $ git branch -vv $ cat .git/gitconfigShowing what remote branches tracked:: $ git remote show $remoteUndo mistaken rebase====================If there are no any ``reset``, ``rebase`` or ``merge`` afterwards the easiestway to recode to pre-rebase state is one of:: $ git rebase --abort $ git reset --hard ORIG_HEADOtherwise look to:: $ git reflogand reset to necessary head:: $ git reset --hard "HEAD@{...}"https://stackoverflow.com/questions/134882/undoing-a-git-rebase Undoing git rebase.Undo reset --hard=================``git reset --hard`` is destructive command without backup data.You may find your previously added data in Git garbage:: $ git fsck --lost-foundlook to files inside ``.git/lost-found`` directory.Reviewing ``git reflog`` also may help.* https://stackoverflow.com/questions/5788037/recover-from-git-reset-hard* https://stackoverflow.com/questions/14251194/how-to-recover-after-i-execute-git-reset-hard-headUndo mistaken push==================:: $ git reset HEAD^ $ git push --forceAlternative commands may look like:: $ git reset --hard $HASH $ git push -u origin master --forceYou can delete remote branch with syntax of appended colon before branch name:: $ git reset HEAD^ $ git push origin :$NAME $ git push origin $NAMEGit bisect==========``bad`` changes should be later in graph history then ``good`` ones. To usealternative names:: $ git start --term-old=... --term-new=...Start bisecting with:: $ git bisect startMark good and bad revisions:: $ git co vBAD $ make test $ git bisect bad $ git co vGOOD $ make test $ git bisect goodIf build/test failed to complete use:: $ git bisect skipTo restore mistakenly marked revisions:: $ git bisect log >$LOG $ git bisect reset $ $EDITOR $LOG $ git bisect replay $LOGImport patch============Check patch summary:: git apply --stat my.patchDetect possible errors during patch application:: git apply --check my.patchApply patch to working tree without commit:: git apply my.patchCommit patch:: git am my.patchCommit patch by signing you as reviewer:: git am --signoff my.patchDebug git network operation===========================Git uses libcurl for network operation:: $ export GIT_CURL_VERBOSE=1 $ git ...Push new repo to remote.========================:: $ mkdir $REPO $ cd $REPO $ git init $ git add . $ git commit -m "Initial commit" $ git remote add origin https://$USER:$PASS@$HOST/$REPO $ git push -u origin masterShow heads in branch.=====================:: $ git show-ref --heads -sSearch string in file=====================To search string in all or specific files or working copy:: $ git grep $PATT $ git grep -i $PATT -- '*.[ch]'To search for string in commit messages:: $ git log --grep $PATT $ git log --grep $PATT --allTo search in all history:: $ git log -S$PATT $ git log --pickaxe-regex=$PATT $ git log -G$PATT $ git grep -i PATT $(git rev-list --all) -- '*.[ch]'.. note:: ``-G`` search occurences in diff chunks, while ``-S`` detects changes in match count.https://git-scm.com/book/en/v2/Git-Tools-Searching Git Tools - Searching.https://stackoverflow.com/questions/1337320/how-to-grep-git-commit-diffs-or-contents-for-a-certain-word How to grep Git commit diffs or contents for a certain word?https://stackoverflow.com/questions/4468361/search-all-of-git-history-for-a-string Search all of Git history for a string?https://stackoverflow.com/questions/2928584/how-to-grep-search-committed-code-in-the-git-history How to grep (search) committed code in the git history?Find most recent tag for revision.==================================:: $ git describe $REVMany projects set tags on branches rather then mainline (for example JS/CSSprojects perform build and commit binary/minified files, which unnecessary formainline history). In this case review simplifiied history by:: $ git log --graph --all --decorate --oneline --simplify-by-decorationList tags with dates.=====================:: $ git log --tags --simplify-by-decoration --pretty="format:%ci %d"Update to date.===============:: $ git checkout 'master@{1979-02-26}' $ git checkout 'master@{1979-02-26 18:30:00}'Using git to work with SVN offline.===================================Prepare SVN and git utilities:: $ sudo apt-get svn git-core git-svnMaking SVN repo:: $ cd $HOME/tmp $ svnadmin create svn-repo $ svn co file://$HOME/tmp/svn-repo svn-devel $ cd svn-devel $ mkdir tags trunk branches $ svn add * A branches A tags A trunk $ cd trunk/ $ printf "all:\n echo XXX\n" >Makefile $ printf "int main() {return 0;}" >main.c $ svn add * $ cd .. $ svn st A trunk A trunk/main.c A trunk/Makefile A branches A tags $ svn ci -m init Adding branches Adding tags Adding trunk Adding trunk/Makefile Adding trunk/main.c Transmitting file data .. $ svn cp -m v0.0 file://$HOME/tmp/svn/trunk file://$HOME/tmp/svn/tags/v0.0 $ svn cp -m v0.1 file://$HOME/tmp/svn/trunk file://$HOME/tmp/svn/branches/v0.1Moving SVN changset to git repo:: $ cd $HOME/tmp $ git svn init file://$HOME/tmp/svn git-repo $ ls -a . .. .git $ git svn fetch A trunk/main.c A trunk/Makefile W: +empty_dir: branches W: +empty_dir: tags r1 = 52ccd9882979dd53ec198dbac108783ec660410f (git-svn) A tags/v0.0/main.c A tags/v0.0/Makefile r2 = 8ec8a772bb6f37ace56b3649066dc84e481ed427 (git-svn) M trunk/Makefile r3 = 2c169ff409ed504dd6a092b1e302beb3fd94871e (git-svn) A branches/v0.1/main.c A branches/v0.1/Makefile r4 = e68d76f4ba6beea4b9059c1884c1f38ce10831a7 (git-svn) M trunk/Makefile r5 = cdde63974454b13ac53f2eeb201aa76c49fd875c (git-svn) Checked out HEAD: file:///home/sasha/tmp/svn r5or (in old git version):: $ git svn clone file://$HOME/tmp/svn git-repoMaking changes in svn:: $ cd $HOME/tmp/svn-devel/trunk $ echo ".PHONY: clean" >>Makefile $ svn ci -m "Added clean to phony." Sending trunk/Makefile Transmitting file data . Committed revision 6.Making committed in git:: $ cd $HOME/tmp/git-repo/trunk $ echo ".PHONY: all" >>Makefile $ echo "int foo(int x) {return x+x;}" >>main.c $ git status # On branch master # Changed but not updated: # (use "git add <file>..." to update what will be committed) # # modified: Makefile # modified: main.c # no changes added to commit (use "git add" and/or "git commit -a") $ git commit -a -m "Bug fixed." Created commit 222d399: Bug fixed. 2 files changed, 2 insertions(+), 0 deletions(-)Getting changes from SVN to git:: $ git svn rebase M trunk/Makefile r6 = 8165e9bfb38e9df09a7313d19606ec227629b670 (git-svn) First, rewinding head to replay your work on top of it... Applying Bug fixed. error: patch failed: trunk/Makefile:6 error: trunk/Makefile: patch does not apply Using index info to reconstruct a base tree... Falling back to patching base and 3-way merge... Auto-merged trunk/Makefile CONFLICT (content): Merge conflict in trunk/Makefile Failed to merge in the changes. Patch failed at 0001. When you have resolved this problem run "git rebase --continue". If you would prefer to skip this patch, instead run "git rebase --skip". To restore the original branch and stop rebasing run "git rebase --abort". rebase refs/remotes/git-svn: command returned error: 1 $ git add Makefile $ git rebase --continue Applying Bug fixed.and return all from git to SVN:: $ git svn dcommit Committing to file:///home/sasha/tmp/svn ... M trunk/Makefile M trunk/main.c Committed r7 M trunk/main.c M trunk/Makefile r7 = 68e782c8d06635f2db4dd69b9ca8599f99da22e2 (git-svn) No changes between current HEAD and refs/remotes/git-svn Resetting to the latest refs/remotes/git-svnSee what going to SVN repo:: $ cd $HOME/tmp/svn-devel/trunk $ svn diff -r BASE:HEAD Index: Makefile =================================================================== --- Makefile (working copy) +++ Makefile (revision 7) @@ -6,4 +6,4 @@ .o: .c $(CC) $(CFLAGS) -c -o $@ $< -.PHONY: clean +.PHONY: all clean Index: main.c =================================================================== --- main.c (working copy) +++ main.c (revision 7) @@ -2,3 +2,4 @@ { return 0; } +int foo(int x) {return x+x;} $ svn up U Makefile U main.c Updated to revision 7.Get latest changes from SVN and update Git repo state:: $ git svn fetch $ git svn rebasegitk.=====gitk - The git repository browser. See gitk(1).Installing:: $ sudo apt-get instal gitkUsing:: $ cd /path/to/git-repo $ gitk