Mark block quot in HTMLe.
.. -*- coding: utf-8; -*-
======
Git.
======
.. contents::
:local:
Setting up git
==============
Debian::
$ sudo apt-get install git
Cygwin::
$ setup.exe -p git
$ apt-cyg install git
After 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.com
git 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 $proj
You can store proxy settings under repository local config file::
$ git config http.proxy http://$user:$passwd@$ip:$port
Start 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
. .. .git
Add 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.c
Show difference
===============
Show difference between index/stage and working tree::
$ git diff
Show 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 -- $path
Show difference in changeset::
$ git show $hash
Show difference between revisions::
$ git diff $rev1..$rev2
$ git diff ORIG_HEAD..HEAD
https://stackoverflow.com/questions/3293607/difference-between-git-head-and-the-current-project-state
Difference between git HEAD and the current project state?
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 badfile
Committing 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 branch
List all known branches::
$ git branch -a
List all known remote branches::
$ git branch -r
List all remote branches (from all remotes)::
$ git ls-remote
$ git ls-remote origin
List registered remotes::
$ git remote show
List remote branches from ``$REMOTE`` remote::
$ git ls-remote --heads $REMOTE
$ git remote show $REMOTE
Special 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 show
Getting branches pointers from default (``origin``) remote (without merging
tracking branch)::
$ git fetch
Getting branches pointers from ``$REMOTE`` remote::
$ git fetch $REMOTE
To get updated with default remote changes::
$ git pull
or specify concrete remote::
$ git pull $REMOTE
$ git pull origin
Delete local branch::
$ git branch -d $NAME
Delete remote branch remotely::
$ git push --delete $REMOTE $BRANCH_NAME
$ git push -d $REMOTE $BRANCH_NAME
$ git push -d origin $BRANCH_NAME
To 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 $HASH
git 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
TODO
To detect if remote repository have new changes::
$ git ls-remote
$ git ls-remote $upstream
View git commits
================
Review specific commit with::
$ git show $REV
$ git diff $REV^ $REV
Review difference between commits::
$ git $REV1 $REV2
$ git $REV1..$REV2
$ git $REV1..$REV2 -- $DIR_OR_FILE
Review history with diffs::
$ git log -p
$ git log -p $FROM_REV
View unpublished git commits / analog of git 'hg outgoing'
==========================================================
``git`` does not directly support such feature. Recently ``hg`` start tracking
changes 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 --remotes
http://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 --decorate
Add alias::
[alias]
glog = log --all --graph
Git 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 external
editor is opened)::
$ git commit -a --amend --no-edit
To edit messages of old commits starting from ``$REV``::
$ git rebase -i $REV
To undo latest commit::
$ git reset HEAD~1
Git analog of 'hg root'
=======================
::
$ git rev-parse --show-toplevel
Making 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 foo
Showing what and how local branches are tracked::
$ git branch -vv
$ cat .git/gitconfig
Showing what remote branches tracked::
$ git remote show $remote
Undo mistaken rebase
====================
If there are no any ``reset``, ``rebase`` or ``merge`` afterwards the easiest
way to recode to pre-rebase state is one of::
$ git rebase --abort
$ git reset --hard ORIG_HEAD
Otherwise look to::
$ git reflog
and 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-found
look 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-head
Git bisect
==========
``bad`` changes should be later in graph history then ``good`` ones. To use
alternative names::
$ git start --term-old=... --term-new=...
Start bisecting with::
$ git bisect start
Mark good and bad revisions::
$ git co vBAD
$ make test
$ git bisect bad
$ git co vGOOD
$ make test
$ git bisect good
If build/test failed to complete use::
$ git bisect skip
To restore mistakenly marked revisions::
$ git bisect log >$LOG
$ git bisect reset
$ $EDITOR $LOG
$ git bisect replay $LOG
Import patch
============
Check patch summary::
git apply --stat my.patch
Detect possible errors during patch application::
git apply --check my.patch
Apply patch to working tree without commit::
git apply my.patch
Commit patch::
git am my.patch
Commit patch by signing you as reviewer::
git am --signoff my.patch
Debug 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 master
Show heads in branch.
=====================
::
$ git show-ref --heads -s
Search string in file
=====================
To search string in all or specific files or working copy::
$ git grep $PATT
$ git grep -i $PATT -- '*.[ch]'
To 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::
``-S`` search occurences in diff chunks, while ``-G`` 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 $REV
Many projects set tags on branches rather then mainline (for example JS/CSS
projects perform build and commit binary/minified files, which unnecessary for
mainline history). In this case review simplifiied history by::
$ git log --graph --all --decorate --oneline --simplify-by-decoration
List 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-svn
Making 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.1
Moving 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 r5
or (in old git version)::
$ git svn clone file://$HOME/tmp/svn git-repo
Making 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-svn
See 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.
gitk.
=====
gitk - The git repository browser. See gitk(1).
Installing::
$ sudo apt-get instal gitk
Using::
$ cd /path/to/git-repo
$ gitk