Git常用命令

这是一篇自从用Git以来备查的写在evernote上整理后的笔记。

基本使用

Git安装后。

第一步:设置名称和邮件

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

第二步:设置ssh-key,这个直接参考Github的帮助文件

复制仓库

git clone git@github.com:foo/bar.git

分支相关 Branch and Checkout

git checkout -b branch_name // 创建分支并切换到develop
git branch -r               // 远程分支列表
git branch -a               // 所有分支
git branch -vv              // 查看本地与远程的对应关系

git checkout branch_name    // 切到某个分支
git checkout -              // 切到上个分支,极好用

Commit

git diff                            //查看一下本次改动
git add .                           //添加所有文件到暂存区
git commit -m "message"             //提交

git commit --amend -m "new message" // 修改提交文字

Push and Pull

git push
git push -u origin branch_name  // -u 即 --set-upstream
// 上述等于 git push --set-upstream origin branch_name
// push分支并绑定远端分支, 以后就可以直接git pull, git push了

git pull                        // git fetch + git merge
git pull --rebase               // git fetch + git rebase

Merge and Rebase

git merge branch_name
git merge --no-ff branch_name  // 必定会产生一条merge commit,不同分支合并时建议使用

mergerebase的区别就不讲了。
不同分支之间的合并用 merge,多人在同一分支上开发,推荐用 rebase

在手头上有commit待push的时候,个人喜好用git pull --rebase,先把小伙伴们的commit跑一遍,这样可以少一个merge commit,在用gitk查看时,也对提交、分支合并等信息一目了然。

(但是,现实是骨感的……

Stash

git stash
git stash pop

手头写的东西没有完成不想commit,又不得不切分支怎么办?
git stash,切分支,干完该干的事情,git checkout -切回来,git stash pop

Reset and Revert

git revert [sha1]

git reset                   //把暂存区的文件移出来

git reset --hard [sha1]     //代码回滚到指定历史节点
git reset --hard HEAD^      //代码强制回滚,谨慎使用。
// n个^表示后退n个commit

git reset HEAD^             //取消最近一次commit,但代码还在,且不在暂存区。

某一个commit想要无效化,但已经是好几个commit之前了,那就用revert,并且会产生一条commit信息
如果要到目前为止的前几个commit无效化,用reset

查看提交历史

git log                 
git log -n                              //查看最近n条提交历史
git log --graph --decorate --oneline    //树状,方便看分支合并情况

gitk                                    //相当于上面那条的GUI版,服务器一般都没有装

衍生使用

删除分支

git branch -d branch_name                   //删除本地分支
git branch -D branch_name                   //强制删除本地分支。分支有分歧时使用

git push origin --delete branch_name        //删除远程分支
git push origin :branch_name                //删除远称分支
git push origin --delete branch1 branch2    //删除多个远程分支

分支改名

git branch -m new_name                      //改本地分支名
git push origin :old_name new_name          //删除远程分支,push新分支
git push origin -u new_name                 //本地分支和远程新分支绑定

远程代码回滚

git reset HEAD^             //先回滚本地
git push origin +HEAD       //再强制把本地的HEAD推上去

merge冲突解决

//解决冲突
git add file_name 或 git add . 
git commit -m 'commit message'  //替代默认的merge message

只会解决一次冲突。

rebase冲突解决

//解决冲突
git add file_name 或 git add .   
git rebase --continue            //继续执行下一个commit

如果发生多次冲突,需要重复上述多次。

另外多说一下, 如果解决冲突得心力交瘁不想干了,可以 git rebase --abort,取消这次rebase,之后可以merge
但是,千万不要途中用git rebase --skip来跳过commit,巨坑!

如何找回reset掉的commit?

git reflog              //查看最近commit、分支切换的log。找到那条commit,复制sha1
git cherry-pick [sha1]  //单独执行某个commit

如果cherry-pick时也遇到冲突了,和rebase的解决办法是一样的。

从tag创建分支

git tab -l -n                           //获得tag列表
git checkout -b branch_name tag_name 

submodule

以前用过一段时间submodule,把一些仓库挂在另一个仓库之下。比较麻烦,现在改用composer依赖库了,姑且记录下。

git clone --recursive           //克隆仓库时,顺便把submodule一起拉下来

git submodule update --init     //初始并更新submodule

Reference

  • http://stackoverflow.com/questions/8225125/remove-last-commit-from-remote-git-repository
  • http://stackoverflow.com/questions/9069061/what-is-the-difference-between-git-merge-and-git-merge-no-ff
  • Git官网