$ ls ~yifei/notes/

Git 使用技巧

Posted on:

Last modified:

最佳实践

每次提交前都使用 git status 查看已经更改的文件,然后使用 git add 逐条添加文件,然后 再看 git status 提交的文件是不是都对的。认真编写 .gitignore 文件,最好能够做到使用 git add . 是安全的。

cherry-pick

cherry-pick 直接翻译意为“挑拣樱桃”,在 git 中的意思是从其他分支上挑拣文件过来。

git co branch -p

本来我以为是 git cherry-pick,但是显然 cherry-pick 和我想的不一样 Push 到远端不同名字的分支

git push origin local-name:remote-name

取消与重置

当你的 commit 已经 push 之后就不能再撤销了,只能使用 revert。

取消上一个 commit

git reset HEAD~1
  • reset --mixed will reset the index not the working dir
  • reset --soft will only move the HEAD
  • reset --hard will even reset the working dir

删掉第一个 commit

git update-ref -d HEAD

重置到 origin 库中的 HEAD

首先,保存到一个分支

git commit -a -m "Saving my work, just in case"
git branch my-saved-work

然后,把 master 分支重置到 origin/master

git fetch origin
git reset --hard origin/master

从 staging area 中删除文件

git reset HEAD <file>  // remove a file from staging area
git reset // to remove all files from staging area

git checkout -- git fetch origin && git reset --hard origin/master

push

git push --tags 推送 tag 到远端仓库

git tag tagname commit_id 给某个 commit 打上标签

git checkout tagname 切换到某个 tag

使用 git bisect 二分查找问题

use bisect to determine when a bug is introduced by specifying a start point and a end point, and doing a binary search between the commits.

git bisect start
git bisect good xxxxxx
git bisect bad xxxxxx
# begin binary search
run test and mark commits
git bisect good/bad
# end of binary search
# git will prompt a first bad commits
# you can use git log to visualize the process
git bisect reset

分支与合并

git push -u origin master
git checkout -b branch_name # create new branch
git checkout master # switch back
git branch -d branch_name # delete branch
git push origin --delete branch_name # delete remote branch
git push origin branch_name # push to remote
git branch branch -v xxxxxx
git merge branch_name # merge branch_name to current branch
git merge --squash
git merge --abort  # 放弃合并

当第一次推送某个分支的时候,需要使用 --set-upstream/-u 来制定要同步的分支。

为了使 commit 记录清晰易懂,不产生无谓的 commit,应该尽量避免和远程分支合并。每次提交尽量使用 pull --rebase,而不是 pull and merge。

git pull --rebase  # 如果有冲突的话,先运行 git stash
git stash # if you and remote change the same file
git stash pop  # pull 之后再 stash pop
git commit -am "some change"
git push

rebase

Once you understand what rebasing is, the most important thing to learn is when not to do it. The golden rule of git rebase is to never use it on public branches.

git rebase origin/master

rebase vs merge

advanced stash

  1. git stash save "stash_name" // save a stash with a name

  2. apply by name

[alias]
sshow = "!f() { git stash show stash^{/$*} -p; }; f"
sapply = "!f() { git stash apply stash^{/$*}; }; f"

use these lines to show and apply stash by name

  1. git stash -p // stashes which files you select

git diff 可以跟时间,来查看一段时间内的改动

显示某个文件谁的改动最多:

git blame file | sort -b -k 3 # sort by date

Git Hooks

最好还是把 git hooks 放到 git 管理的文件中,这样项目中的其他人才方便使用同一个标准。

git config --local core.hooksPath .githooks/

使用这条命令更改默认的 .git/hooks 目录

分支

One branch to rule them all. Branches are meant to be merged

长期存在的 branch 只应该有一个,不应该有单独的 develop branch。 分支的最终意义就是被合并,而不是单独存在。即使是独立部署,那么应该分两个仓库,或者使用条件语句

Put everything on the HEAD

所有的改动都应该在主分支上,确保主分支随时都是测试过得,可以直接部署的。

Use tags

对于每次部署等活动,使用 tag

参考

  1. https://stackoverflow.com/questions/3462955/putting-git-hooks-into-repository
  2. https://stackoverflow.com/questions/9339429/what-does-cherry-picking-a-commit-with-git-mean
  3. https://github.com/jiffyclub/blog-posts/blob/master/git-pushing-to-a-remote-branch-with-a-different-name.md

© 2016-2022 Yifei Kong. Powered by ynotes

All contents are under the CC-BY-NC-SA license, if not otherwise specified.

Opinions expressed here are solely my own and do not express the views or opinions of my employer.