Git命令行使用手册

基本命令和理解

git --help

不多说,会给你命令提示

git init

初始化版本库
git init --bare
创建一个裸体仓库,它只包含.git 里面的文件,不会包含工作目录的文件,这个仓库只保存git历史提交的版本信息,而不允许用户在上面进行各种git操作,用来当作远端‘根源库’,用来记录所有仓库的git操作,有了它才能有push的操作。
如何基于这个裸体仓库,创建本地库呢?

  1. 新建文件夹,初始化版本库和添加指定到这个根源库,就可以在这个文件夹下有个本地仓库了
    git init & git remote add <根源库>
  2. 克隆
    git clone <根源库地址> <本地库名>
    参数-o, –origin
    use instead of ‘origin’ to track upstream

git pull

git pull
是git fetch+git merge FETCH_HEAD的缩写.

完整格式是
git pull <远程库名> <远程分支名>:<本地分支名>

如取回远程库中的develop分支,与本地的develop分支进行merge,要写成
git pull origin develop:develop
如果是要与本地当前分支merge,则冒号后面的<本地分支名>可以不写。
git pull origin develop

如果远程主机删除了某个分支,默认情况下,git pull 不会在拉取远程分支的时候,删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致git pull不知不觉删除了本地分支。
但是,你可以改变这个行为,加上参数 -p 就会在本地删除远程已经删除的分支。
git pull -p
等同于下面的命令
git fetch --prune origin
git fetch -p

git stash (贮藏)

当本地有文件改动的时候,需要commit后才能pull,如果我不想commit也能pull的时候,就可以用stash

1
2
3
$ git stash save "XXXX"
$ git pull --rebase
$ git stash pop //或者git stash apply

pop会apply后删除这条贮藏信息,apply着不会删除

git log

git log
查看commit的历史

git show <commit-hash-id>
查看某次commit的修改内容

git log -p <commit-hash-id>
等效上面

git log -p <filename>
详细查看某个文件的修改历史

git log -p -2
查看最近2次的更新内容
然后你就可以使用 less 中常用的检索命令即“斜杠”后面加检索词/),在变更内容日志中检索指定的关键词(使用小写的n跳到下一条检索结果,大写的N跳到上一条检索结果)

git log -L 1,1:some-file.txt
查看文件中指定位置的变更
你还可以 git blame filename 追查出文件中每一行是由谁变更的。

git log --since=7.days --author=Jacks --grep=init -2
7.days指最近7天,作者为“Jacks”的,提交含有关键字’init’的,-2指获取前最近前2条记录。

git log --committer=Jack
如指定提交者为”Jack”的所有提交,注意的是作者名字是有大小写之分的

来看一个实际的例子,如果要查看 Git 仓库中,2008 年 10 月期间,Jacks 提交的但未合并的测试脚本(位于项目的 t/ 目录下的文件),可以用下面的查询命令:
git log --pretty="%h - %s" --author=Jacks --since="2008-10-01" --before="2008-11-01" --no-merges -- t/

git branch

  1. 查看所有分支 git branch -a
  2. 查看本地分支 git branch
  3. 创建分支 git branch test
  4. 切换分支 git checkout test (会去远端匹配名字为test的分子,存在会在本地创建一个对应的本地分子,如果远端本地都没有则会失败)
  5. 切换到远端分支 git checkout remotes/origin/test
  6. 根据当前分支创建+切换一个新分支 git checkout -b branch-name
  7. 删除本地分支 git branch -d branch-name
  8. 删除远端分支 git push origin :branch-name (提交一个空分支覆盖远端分支)或者 git push origin --delete branch-name
  9. 删除本地对远端分支的链接 git branch -r -d origin/branch-name (本地没了,远端服务器上还在)

git remote

不带选项的时候,git remote命令列出所有远程主机。

1
2
$ git remote
origin

使用-v选项,可以参看远程主机的网址。

1
2
3
$ git remote -v
origin git@github.com:jquery/jquery.git (fetch)
origin git@github.com:jquery/jquery.git (push)

克隆版本库的时候,所使用的远程主机自动被Git命名为origin。如果想用其他的主机名,需要用git clone命令的-o选项指定。

1
2
3
$ git clone -o jQuery https://github.com/jquery/jquery.git
$ git remote
jQuery

上面命令表示,克隆的时候,指定远程主机叫做jQuery。

  1. 查看该主机的详细信息
    git remote show <主机名>
  2. 添加远程主机
    git remote add <主机名> <网址>
  3. 删除远程主机
    git remote rm <主机名>
  4. 远程主机的改名
    git remote rename <原主机名> <新主机名>

git tag

  1. 开始创建标签,创建标签的两种方式:

    1
    2
    $ git tag -a v0.1.0 -m "第一个版本"  //创建标签, -a 加标签,-m  加标签注释。
    $ git tag v0.1.0 //创建轻量级标签,不用-a,-m等参数
  2. 查看创建的标签

    1
    2
    $ git tag            //列出git中现有的所有标签
    $ git show v0.1.0 //git show 命令查看相应标签的版本信息,并连同显示打标签时的提交对象
  3. 加上-f 覆盖原有的tag
    git tag -f v0.1.0

  4. 如果要一次推送所有本地新增的标签上去,可以使用 –tags
    git push origin --tags
    注:普通的git push origin master操作不会推送标签到服务器端。

  5. 推送指定的标签±
    git push origin v0.1.0

  6. 删除本地标签
    git tag -d v0.1.0

  7. 删除服务器标签
    git push origin :refs/tags/v0.1.0

git merge

--no-ff
指的是强行关闭fast-forward方式。

fast-forward
方式就是当条件允许的时候,git直接把HEAD指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建commit

git merge --squash
是用来把一些不必要commit进行压缩,比如说,你的feature在开发的时候写的commit很乱,那么我们合并的时候不希望把这些历史commit带过来,于是使用–squash进行合并,此时文件已经同合并后一样了,但不移动HEAD,不提交。需要进行一次额外的commit来“总结”一下,然后完成最终的合并。

总结:
--no-ff
不使用fast-forward方式合并,保留分支的commit历史
--squash
使用squash方式合并,把多次分支commit历史压缩为一次

git reset

在git中,有3种类型的重置文件。重置是让文件回到git历史中的一个特定版本。
git reset –hard NaN
回退到一个特定的历史版本。丢弃这次提交之后的所有变更。
git reset NaN
回滚到一个特定的历史版本。将这个版本之后的所有变更移动到“未暂存”的阶段。这也就意味着你需要运行 git add . 和 git commit 才能把这些变更提交到仓库.
git reset –soft NaN
回滚到一个特定的历史版本。将这次提交之后所有的变更移动到暂存并准备提交阶段。意味着你只需要运行 git commit 就可以把这些变更提交到仓库。

git clean

从工作树中移除未跟踪的文件,比如项目中新建或者复制,拖入的文件,还没进行git add的文件,我们突然不想要了,就可以把它们清理掉,如果是文件夹,加上参数-d即可

高阶玩法

git pull --rebase

默认情况下,git pull就是先fetch,然后执行merge 操作,如果加–rebase 参数,就是使用git rebase代替git merge.

修改git pull默认merge操作为rebase

1
$ git config --global pull.rebase true

每次 git pull就变成fetch+rebase,等效于git pull –rebase

git rebase -i

Git没有一个修改历史的工具,但是你可以使用rebase工具来衍合一系列的提交到它们原来所在的HEAD上而不是移到新的上。依靠这个交互式的rebase工具,你就可以停留在每一次提交后,如果你想修改或改变说明、增加文件或任何其他事情。你可以通过给git rebase增加-i选项来以交互方式地运行rebase。你必须通过告诉命令衍合到哪次提交,来指明你需要重写的提交的回溯深度。
例如,你想修改最近三次的提交说明,或者其中任意一次,你必须给git rebase -i提供一个参数,指明你想要修改的提交的父提交,例如HEAD2或者HEAD3。可能记住~3更加容易,因为你想修改最近三次提交;但是请记住你事实上所指的是四次提交之前,即你想修改的提交的父提交。

1
$ git rebase -i HEAD~3

修改commit信息

HEAD~3范围内的每一次提交都会被重写,无论你是否修改说明。
注意:不要涵盖你已经推送到中心服务器的提交——会使其他开发者产生混乱,因为你提供了同样变更的不同版本。
修改提交说明,退出编辑器。然后,运行在输入上边命令后的结果中,将你想修改的每一次提交前面的pick改为edit,保存退出
根据提示,运行

1
$ git commit --amend

修改提交说明,退出编辑器。然后,运行

1
$ git rebase --continue

这个命令会自动应用其他两次提交,你就完成任务了。如果你将更多行的pick 改为
`edit你就能对你想修改的提交重复这些步骤。Git每次都会停下,让你修正提交,完成后继续运行。

合并多次commit信息

通过git rebase -i HEAD~~~进入编辑模式,使用squash命令(本文使用简写”s“,该命令用于合并多次提交),并保存退出;
这里需要注意的是

  1. 信息会倒序排列
  2. 需要保留一个pick,作为squash压缩后的点(保留哪一个提交点,根据你需要保留哪个点的信息)
    然后将三次提交的commit信息合并为一次提交的commit信息。保存退出。
    我们再次通过git log查看提交信息,此时只有一次提交的commit信息。
    这里也可以单单修改的每一次提交的commit信息,只需要前面的pick改为r,保存退出。
    以上参数git均有英文提示。

注意
果有多次commit,可以用HEAD~选取哪几次,不带HEAD参数,就是全部的commit。

修改远端log提交的某条日志

命令如下:

1
2
3
4
5
6
//找到你要修改的那条log的id
$ git log
//假设id是0b58225,找到你要修改的那一条,把前面的pick改成r,保存退出
$ git rebase -i 0b58225~1
//修改好commit后,执行下面命令,强制push远端(会完全覆盖,谨慎操作,确保你当前和远端是最新的,不然会抹点远端别人提交的)
$ git push -f (建议push指定分支,以免影响其他分支)

删除本地库中与远端不存在的跟踪分支(tracking branches)

当远端分支被强制删除后,本地库中对远程分支的记录并不会同步更新,所以当我们git branch -a的时候会发现很多多余的remote/origin/xxxx分支(tracking branches)实际上远端已经不存在了。
我们可以用

1
2
3
4
//方法一
$ git fetch [origin] -p //[origin]可以为空,为空为默认源的名字,参数p等同prune,意思是除去所有的远端处不再存在的任何远端跟踪分支
//方法二
$ git remote prune [origin] //git remote 我们知道是管理已经跟踪的库,功能同上

美化Git显示漂亮日志的小技巧

命令行如下:

1
2
3
4
5
6
7
8
$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --

这样有点长了,我们可以这样:

$ git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --"

然后,我们就可以使用这样的短命令了:
$ git lg

重新鞭策你的记录(找回丢失的commit)

Git reflog 可以查看所有分支的所有操作记录,包括已经被删除的commit记录,git log则不能察看已经删除了的commit记录
具体一个例子,假设有三个commit
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
如果执行git reset –hard HEAD1则 删除了commit3,如果发现删除错误了,需要恢复commit3,或者rebase遇到冲突误操作的时候,就可以使用git reflog找到之前的操作记录
HEAD@{0}: HEAD
1: updating HEAD
5201314 HEAD@{1}: commit: test3:q
红色加粗的即是被删除了的 commit3,运行git log则没有这一行记录
可以使用git reset --hard 5201314将红色记录删除,则恢复了cmmit3,运行git log后可以看到:
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
这里也可以使用另外一种方法来实现:git cherry-pick 5201314

其实学习园区

Git Community Book 中文版

对 Linux 新手非常有用的 20 个命令

0%