2015年11月25日 星期三

GIT handbook

--------------------------------------------------------------------------------------------------------------------
GIT DIFF
--------------------------------------------------------------------------------------------------------------------
List the file names only that changed between two commits:
$ git diff --name-only [commit1] [commit2] [file3]

List the file names (and some more detail) that changed between two commits:
$ git diff --stat svr/bl2 svr/bl3
$ git diff --name-status [SHA1 [SHA2]]
Show diff using graphics GUI:
$ git difftool -t meld  [commit1] [commit2] [file3]

git diff [-- folder/file] => workspace vs staged
git diff HEAD => workspace vs HEAD
git diff --cached [HEAD] => staged vs HEAD
git diff HEAD^ HEAD => HEAD^ vs HEAD

--------------------------------------------------------------------------------------------------------------------
GIT  all
--------------------------------------------------------------------------------------------------------------------
Remove local untracked files from workspace:
$ git clean -f -d -n         # -d to include folders;  -n for dry run
$ git clean -f -d -x         # -x to ignore .gitignore

List all branches/tag:
$ git branch -a
$ git tag
$ git ls-remote --tags
List all tags and their SHA:
$ git show-ref --tag

Remove a local branch:
$ git branch -d
$ git branch -D

Remove a local tag:
$ git tag -d <tag>


Remove a remote branch/tag:
$ git push :<branch/tag>

Fetch a repository from a remote (update database only):
$ git fetch --prune

Multiple remotes, pushed (and fetched) independently:$ cd myproject
$ git remote add bitbucket ssh://git@bitbucket.org/user/myproject.git
$ git push bitbucket master
Single remote with multiple URLs, pushed (and fetched) consecutively.
$ cd myproject
$ git remote set-url --add origin ssh://git@bitbucket.org/user/myproject.git 
$ git push origin master

Revoke recent 2 commits:
git reset HEAD~2

List SHA and comment, one line per one commit, from bl2 to bl3:
$ git log --pretty=oneline --author=flxm.com svr/bl2..svr/bl3

Replay the the patches, from the common ancestor of the bl2 and dev branches, onto dev2:
$ git rebase --onto dev2 svr/bl2 svr/dev1

Display history:
$ gitk --all --select-commit=svrX/branchY

Change commit author at one specific commit
For example, if your commit history is A-B-C-D-E-F with F as HEAD, and you want to change the author of C and D, then you would...
  1. Specify git rebase -i B
  2. change the lines for both C and D to edit
  3. Once the rebase started, it would first pause at C
  4. You would git commit --amend --author="Author Name "
  5. Then git rebase --continue
  6. It would pause again at D
  7. Then you would git commit --amend --author="Author Name " again
  8. git rebase --continue
  9. The rebase would complete.

List all authors
$ git log --format='%aN <%aE>'
$ git log --format='%aN>' | sort -u
List everyone who committed to a particular project, listed alphabetically. To list by commits, add -n to the shortlog.
$ git shortlog -s | cut -c8-
Gets the authors, sorts by number of commits (as a vague way of estimating how much of the project is their work, i.e. the higher in the list, the more they've done) and then outputs the results.
$ git log --format='%aN <%aE>' | awk '{arr[$0]++} END{for (i in arr){print arr[i], i;}}' | sort -rn | cut -d\  -f2-

Cherry-pick only changes to certain files
git cherry-pick -n 

# unstage modifications you don't want to keep, and remove the
# modifications from the work tree as well.
# this does work recursively!
git checkout HEAD 

# commit; the message will have been stored for you by cherry-pick
git commit
If the vast majority of modifications are things you don't want, instead of checking out individual paths (the middle step), you could reset everything back, then add in what you want:
# unstage everything
git reset HEAD

# stage the modifications you do want
git add 

# make the work tree match the index
# (do this from the top level of the repo)
git checkout .
Q: .gitignore doesn't work
A1: for every line, remove all invisible tailing characters, including SPACE; CR,LF,NULL are OK.
A2: use below commands.  If history was pushed to remotes, rework is needed to clean remote history.
git rm -r --cached .
git add .
git commit -m "fixed untracked files"
Q: List commits w/ logs containing a keyword.
A: git log --grep="keyword"

Q: fast forward to branch head
A: git merge /.

Q: find possible filenames in commits
A: git log --name-only | grep

Q: list commits modify a file
A: git log --follow --

Q: show SHA of the commit before a specific commit
A: git log ^1

Q: show SHA of all commits on a specific branch
A: git log --pretty=format:'%H'

Q: check if a given commit on a specific branch
A: git log --pretty=format:'%H' | grep

Q: show history for a sub directory
A: git log --

Q: show commit ID of tags/branches
A: git show-ref

Q: show commit ID of current commit
A: git log --pretty=format:'%h' -n 1

Q: list tags points to given commit ID
A: git tag --points-at

Q: list tags points to current commit
A: git tag --points-at `git log --pretty=format:'%h' -n 1`

Q: List all files currently under source control of a specific branch.
A: git ls-tree -r --name-only

Q: List of all files that ever existed
A: git log --pretty=format: --name-status | cut -f2- | sort -u

Q: checkout certain revision of a file under a new name
A: git show HEAD^:main.cpp > old_main.cpp

Q: Resolve Git merge conflicts in favor of their changes during a pull
A: git merge --strategy-option theirs

Q: How to checkout src/main.c to another filename?
A: git show HEAD~4:src/main.c > main.c.prev4

Q: How to view the change history of a file?
A: git log -- [filename]
    gitk --follow [filename]

Q: How to see remote tags?
A: git ls-remote --tags <remote>

Q: How to list branches that contain a given commit?
A: git branch --contains <commit>

Q: How to archive all files modified ?
A: git archive -o update.zip <dst_commit> $(git diff --name-only <src_commit> <dst_commit>)

Q: How to show stashes in gitk without `--all` option?
A: gitk `git stash list --format=%H` &

Q: How to show current branch?
A: git branch | grep '*'

--------------------------------------------------------------------------------------------------------------------
GIT patch create & apply
--------------------------------------------------------------------------------------------------------------------
  • git format-patch --root
    • 從root到指定commit的patch
  • git format-patch -n
    • 起, 最近n個commit的patch
  • git format-patch 5e86795..f2b286a
    • 從指定起始commit到結束commit的patch
-o 可以設定輸出的資料夾
git am 0001-modify-page.patch


--------------------------------------------------------------------------------------------------------------------
GIT configuration
--------------------------------------------------------------------------------------------------------------------
git config --global commit.template $HOME/.gitmessage.txt
git config receive.denyDeleteCurrent false

--------------------------------------------------------------------------------------------------------------------
REPO
--------------------------------------------------------------------------------------------------------------------
Add remote for all repositories listed in the manifest.xml.
$ repo forall -c "git remote add ssh://@/home//\$REPO_PROJECT"

List tags points to current commit for all repositories
$ repo forall -c "pwd; git tag --points-at \`git log --pretty=format:'%h' -n 1\`"

Apply manifest to another work space
yulin@WNC:/HOUSE/yulin/mdm9607-le-2-1_amss_standard_oem_r00040p1_PostCS/apps_proc$ repo forall -c "cd /HOUSE/yulin/ptr9628/apps_proc/\$REPO_PATH; pwd; git tag LE201r00075.1 \$REPO_RREV"

--------------------------------------------------------------------------------------------------------------------
Account
--------------------------------------------------------------------------------------------------------------------

  • ssh-keygen -t rsa 或 ssh-keygen -d (dsa) => 產生出 id_rsa, id_rsa.pub
  • scp id_rsa.pub server_hostname:~/.ssh/
  • ssh server_hostname
  • cat .ssh/id_rsa.pub >> .ssh/authorized_keys 即可
  • 這樣子就可以 key 認證登入, 不需輸入密碼

--------------------------------------------------------------------------------------------------------------------
'git log' and 'git show-ref' show different SHA1
--------------------------------------------------------------------------------------------------------------------
~/9150w$ git show-ref --deref v00.07.2k.00
2c79b9c8211db8df33b3e3e387a41edd8a391b72 refs/tags/v00.07.2k.00
b1895be23436bd74642bbd7cc9b0177e70177848 refs/tags/v00.07.2k.00^{}

~/9150w$ git show-ref v00.07.2k.00
2c79b9c8211db8df33b3e3e387a41edd8a391b72 refs/tags/v00.07.2k.00

~/9150w$ git log -n 1  v00.07.2k.00 | grep commit
commit b1895be23436bd74642bbd7cc9b0177e70177848

Refer to https://stackoverflow.com/questions/2534773/what-is-dereference-in-the-context-of-git-show-ref-d,
command "git tag <tag> <branch or HEAD or alike>" is suspected to create an annotated tag.
command "git tag <tag>" creates a lightweight tag.



# Show commits that contains the code, then you can: git show <commit_sha>
git log -S "whatever you want to search for"

# An even easier way to show matches right there on the spot
git log -S "your search term" -p

# Same as above, except applied to all branches instead of the checked out branch
git log -S "something" -p --all

# Limit your search to only specific files in a specific directory
git log -S "something specific" -p -- **/models/user*.py

# Search for a regex instead of a string (note the -G instead of -S)
git log -G '^alias \w+=".*"$' -p

# a string or regular expression with the same flag
git log --grep "your search term"

# Same as above, except applied to all branches instead of the checked out branch
git log --grep "something else" --all


沒有留言: