05_Git常用功能总结

Git常用功能总结

Git基础

用户名和邮箱配置

$ git config [--global] user.name "<username>"
$ git config [--global] user.email "<useremail>"
  • 如果省略--global选项,配置只对当前仓库生效
  • 否则就对当前用户的所有仓库有效
  • 就近原则,本地配置比全局配置的优先级更高

获取帮助

获取详细帮助信息

$ git help <cmd>
$ git <cmd> --help
$ man git-<cmd>

获取简略帮助信息

将上面的三个命令的help替换成h即可获得简略信息

获取仓库的两种方式

初始化一个目录为一个新的仓库

  1. 在某一目录执行以下命令,便可将该目录转变成一个Git仓库

    $ git init
    
  1. 命令执行之后会生成一个.git文件夹

克隆一个已经存在的仓库

  1. 使用以下命令克隆一个仓库

    $ git clone <url> [<name>]
    
  1. 其中<url>为需要克隆的仓库的地址,<name>是可选的,即克隆到本地的仓库的名字,如果没有这一选项,就在本地创建一个和克隆处名字一样的本地库

记录每次更新到Git仓库

查看文件状态

$ git status

暂存新建或者是已修改的文件

$ git add <filename>/<dirname>
  • 其后也可以是一个目录
  • 如果是目录,就递归地将目录中的已修改的文件暂存到暂存区

状态简览

  1. 使用git status命令的状态结果可能略显繁琐

  2. 我们可以使用--short或者是-s选项,使得输出简化

    $ git status -s
    

忽略文件.gitignore

可以在仓库根目录之下创建一个.gitionore文件,在其中指定不进行版本管理的文件

文件差异对比

工作区和暂存区的文件差异的对比
$ git diff [<filename>]
  • 其中<filename>是可选的,如果没有,就会输出所有的文件的差异
本地库和暂存区的文件差异对比
$ git diff --cached/--staged [<filename>]
工作区和本地库的最新版的文件差异对比
$ git diff HEAD -- [<filename>]

提交更新

  1. 在编辑器中输入提交信息

    $ git commit
    
    • 该命令会将暂存区中的文件一次性全部提交到本地库
  2. 使用-m选项携带提交信息

    $ git commit -m "<msg>"
    
  3. 跳过使用暂存区域

    $ git commit -a -m "<msg>"
    
    • 该命令会将==已跟踪==的文件全部暂存然后一次性提交
    • 对于==未跟踪==文件,不会进行暂存和提交

移除文件

  1. 将三个区中的文件进行移除

    $ git rm <filename>
    
  1. 保留工作区中的文件

    $ git rm --cached <filename>
    
  1. 工作区和本地库版本不一致的文件,需要使用-f选项进行强制删除

  2. 对于未追踪的文件,不能使用该命令,实际上直接使用rm命令删除就行了

移动或者重命名文件

$ git mv <fromfile> <tofile>

这相当于

$ mv <from_file> <to_file>
$ git rm <from_file>
$ git add <to_file>

查看提交历史

git log 
  • 常用的选项

    选项 说明
    -p 按补丁格式显示每个提交引入的差异
    -n 仅输出最近的n条提交记录
    --stat 显示提交的文件修改的统计信息
    --shortstat 只显示--stat中最后的行数添加删除统计
    --name-only 仅在提交信息后显示已修改的文件清单
    --name-status 显示新增、修改和删除的文件清单
    --abbrev-commit 仅显示SHA-1校验和的前几个字符
    --relative-date 使用较短的相对时间而不是完整的日期格式显示日期
    --graph 在日志旁使用ASCII图形显示分支与合并历史
    --pretty 自定义日志的输出显示格式
    --oneline --pretty=oneline --abbrev-commit合用的简写
  • 限制日志输出长度的常用选项

    选项 说明
    --author 只显示指定作者修改的提交记录
    --grep 只显示提交说明中包含--grep选项指定的关键字的提交记录
    -num 只显示最后的num个提交记录
    --since or --after 只显示指定日期之后的提交记录
    --until or --before 只显示指定日期之前的提交记录
    --committer 只显示指定提交者提交的记录
    -S 只显示文件数据中添加或者是删除了包含-S选项指定的字符串的提交记录

撤销操作

修补提交

  1. 提交之后想要修改提交信息,不修改文件内容

    $ git commit --amend
    
    • 执行该命令之后Git会让你重新输入提交信息,然后覆盖上一次提交的信息
  2. 不仅修改提交信息,还修改实际的提交内容

    • 先对文件进行修改

    • 再执行下面的命令

      $ git commit --amend
      
- 最后就会使用新的提交覆盖掉上一次的提交
  1. 仅修改提交内容,不修改提交信息

    $ git commit --amend --no-edit
    

版本回退

仅移动HEAD以及其所指的分支
$ git reset --soft HEAD~/HEAD^n
  • 一个~号表示回退一个版本
  • ^nn表示回退的版本数
HEAD所指向的分支指向的提交版本的文件复制到暂存区中
$ git reset [--mixed] HEAD~/HEAD^n
覆盖工作区的内容
$ git reset --hard HEAD~/HEAD^n
取消暂存的文件
$ git reset [HEAD] <file>
  • 这实际上就是使用HEAD所指向的分支的当前提交的版本的<file>覆盖暂存区中的相应文件
压缩
  1. 在我们进行了一次提交之后,再次对文件进行修改

  2. 然后执行如下命令

    $ git reset --soft HEAD~ 
    
  1. 然后再执行

    $ git commit
    
  1. 就相当于将上一次的提交给覆盖了。当然,实际上那个提交依然存在

引用日志

使用如下命令可以查看引用日志

$ git reflog

根据引用日志可以返回到更新的版本

  1. 使用引用日志命令,找到想要到的指定版本的校验和

  2. 执行如下命令

    $ git reset --hard/--soft/[--mixed] <checksum>/HEAD@{<n>}
    
  3. 就可以回到前面的版本

检出(checkout)

不带路径(切换分支)
$ git checkout <point>
  • HEAD指向<point>
带路径(撤销对文件的修改)
$ git checkout -- <file>
  • 实际上就是不移动HEAD,而是将HEAD所指的分支当前指向的提交版本的<file>覆盖暂存区中的对应文件,同时覆盖工作区中的对应文件

远程仓库的使用

远程仓库查看

  1. 查看远程库列表

    $ git remote
    
  1. 查看远程库列表的详细信息

    $ git remote -v
    

添加一个远程库

$ git remote add <name> <url>
  • <name>是远程库的简写名称
  • <url>是远程库的具体地址

抓取远程库的数据到本地

$ git fetch <name>/<url>
  • <name>远程库的简称
  • <url>远程库的具体地址

合并数据到本地分支

$ git merge <name>/<branch>
  • 该命令将远程库<name><branch>分支的内容合并到当前的分支上

拉取远程库上的指定分支的内容

$ git pull <name>
  • <name>为远程库的简称
  • 要使用该命令,必须先将本地库的当前分支与远程库的分支进行关联
  • 该命令会将远程库上的内容下载到本地并将和当前分支关联的远程分支与当前分支进行合并

推送到远程库

$ git push <name> <master>
  • <name>是远程库的名称
  • <master>实际上可以是其他分支

查看某个远程仓库

$ git remote show <name>
  • <name>为远程仓库名

远程仓库重命名

$ git remote rename <oldname> <newname>
  • 该命令也就是更改本地对于远程库的称呼,并非将远程仓库的仓库名字改了

远程仓库的移除

$ git remote remove/rm <name>
  • 该命令只是将和远程仓库关联的远程仓库简写名称从本地删除了,也就是说以后我们的仓库不能再连接相应的远程库了,而不是说我们真的把一个仓库从远程服务器上移除了

打标签

列出标签列表

  1. 列出所有标签

    $ git tag
    
  1. 列出满足一定条件的标签

    $ git tag -l/--list <regex>
    
    • <regex>为一个筛选条件,可以是一个正则表达式

创建标签

创建附注标签
$ git tag -a <tagName> -m "<msg>"
  • <tagName>为标签名
  • <msg>为标签信息
查看标签信息以及打标签的提交的提交信息
$ git show <tagname>
创建轻量标签
$ git tag <tagname>
附注标签和轻量标签的区别

附注标签附带这标签信息,轻量标签没有标签信息。轻量标签就相当于一个简单的标记。

补打标签

这个和为当前版本的提交打标签类似,不过就是再最后增加一项,也就是想要打标签的提交的校验和(或者部分检验和)

共享标签

  1. 将某一个标签显示推送到远程服务器

    $ git push <remote> <tagname>
    
    • <remote>为远程库名称
    • <tagname>为要推送的标签名
  2. 将所有标签一次性全部推送到远程服务器

    $ git push <remote> --tags
    

删除标签

删除本地标签
$ git tag -d <tagname>
删除共享到远程服务器上面的标签
  1. 第一种方式

    $ git push <remote> : ref/tags/<tagname>
    
  1. 更直观的方式

    $ git push <remote> --delete <tagname>
    

检出标签

$ git checkout <tagname>
  • 这实际上就是将HEAD指向<tagname>所指向的提交
  • 这回导致仓库处于头指针分离状态
  • 在这种状态下,我们如果要进行新提交,一般要先新建一个分支

Git别名

为Git内部的命令起别名

$ git config [--global] alias.<title> '<cmd>'
  • 其中,如果有[--global],那么这个命令的别名就会在整个当前用户都有效,这些配置文件在Git的全局配置文件中
  • 如果没有[--global],那么这个别名就只在本仓库生效,配置信息在当前仓库的.git文件夹下的.gitconfig文件中
  • <title>为命令别名
  • <cmd>为要起别名的具体命令

为Git外部的命令起别名

$ git config [--global] alias.<title> '!<cmd>'
  • 可以看出,和为内部命令起别名的区别就是要在外部命令前添加一个!

Git 分支

查看当前仓库的所有分支

$ git branch

分支的创建

创建分支

$ git branch <branchname>

切换分支

$ git checkout <branch>

或者是

$ git switch <branch>

创建并切换分支

$ git checkout -b <branch>

或者是

$ git switch -c <branch>

查看各分支所指向的提交对象

$ git log --decorate

查看各分支的更加详细信息

$ git log --oneline --decorate --graph --all

分支的合并

$ git merge <master> <dev>
  • <master>表示要并入的主分支
  • <dev>表示要被合并的分支
  • 就是要将<dev>的内容合并到<master>
  • 如果省略<master>分支,默认将<dev>分支合并到当前分支

分支的删除

  1. 删除已经进行了合并的分支

    $ git branch -d <branch>
    
  1. 删除一个还没有和其他分支进行合并的分支

    $ git branch -d -D <branch>
    
    • -D表示强制删除

分支合并产生冲突的解决办法

  1. git status查看冲突的文件
  2. 对于有冲突的文件进行手动修正
  3. git add将冲突文件暂存
  4. git commit将暂存的文件进行提交
  5. 合并完成

分支管理

列出所有分支

$ git branch

查看每一个分支的最后一次提交信息

$ git branch -v

查看已经和指定分支进行了合并的分支

$ git branch --merged [<branch>]
  • 如果省略后面的分支名,则默认为当前分支

查看还没有和指定分支进行过合并的分支

$ git branch --no-merged [<branch>]

远程分支

获取远程引用(包括分支、标签等)的完整列表

$ git ls-remote <remote>

或者是

$ git remote show <remote>

将分支推送到远程库上

远程库分支和本地分支名字相同
$ git push <remote> <branch>
给远程分支起名字
$ git push <remote> <localName> : <remoteName>

本地分支和远程分支的合并

和已有分支合并
$ git merge [<localBranch>] <remote>/<remoteBranch>
  • <remote>/<remoteBranch>分支合并到<localBranch>分支
  • 若缺省本地分支名称,默认为当前分支
基于远程分支新建一个本地分支
$ git checkout -b <newBranch> <remote>/<branch>
  • 这相当于新建的分支的起点和远程分支的一致
  • 这实际上就创建了一个跟踪分支<newBranch>

跟踪分支

跟踪分支就是和远程分支关联起来了的本地分支。在一个跟踪分支上面执行pull命令,Git会抓取到正确的远程分支的内容,然后自动合并到跟踪分支上。

创建跟踪分支
  1. 常规创建方法

    $ git checkout -b <newBranch> <remote>/<branch>
    
  1. 创建一个和远程分支同名的跟踪分支

    $ git checkout --track <remote>/<branch>
    
设置跟踪分支
$ git branch -u/--set-upstream-to <remote>/<branch>
  • 设置当前分支为跟踪分支,其上游分支为<remote>/<branch>
上游快捷方式

可以使用@{u}或者是@{upstream}来引用跟踪分支的上游分支

查看所有的跟踪分支
$ git branch -vv

获取数据并合并

抓取
$ git fetch <origin>
合并
$ git merge [<localBranch>] <remote>/<branch>
拉取

对于跟踪分支,可以直接使用

$ git pull [<remote>]

命令进行自动抓取和合并

删除远程分支

$ git push <remote> --delete <branch>

变基

普通的变基操作

$ git rebase <A> [<B>]
  • <B>分支变基到<A>分支上

  • 如果缺省<B>选项,就默认将当前分支变基到<A>分支上

  • 变基之后还要进行快进合并操作才能完成最终的变基

    $ git checkout <A>
    $ git merge <B>
    

高级变基操作

$ git rebase --onto <a> <b> <c>
  • 将在<c>上但是不在<b>上的提交历史变基到<a>

  • 进行快进合并

    $ git checkout <a>
    $ git merge <c>
    

Git工具

分支引用

我们可以使用一个分支指针来指定一个提交记录。此时该记录就是分支指针所指向的当前提交记录。例如

$ git show master

引用日志

  1. 引用日志和一般日志的区别是:引用日志记录了HEAD以及分支指针指向的变化,而日志就是记录了提交历史的变化。引用日志会记录每一次Head或者是个分支指针的变化。在我们刚克隆一个仓库的时候,所得仓库的引用日志是空的,这说明引用日志记录的是本地仓库的指针在本地经历的变化。

  2. 查看引用日志

    $ git reflog
    
  1. 使用show查看具体的某一个引用日志

    $ git show <checksum>/HEAD@{<N>}
    
  1. 查看一个指针在指定时间之前所在的位置

    $ git show <branch>@{<time>}
    
  1. 使用如下命令可以查看类似于git log输出格式的引用日志信息

    $ git log -g
    

祖先引用

脱节符(^

  1. 在一个指针之后添加一个脱节符^,表示该指针的父提交(它所指向的前一个提交)。

    $ git show master^
    
    • 表示显示master分支所指向的提交的父提交的信息
  2. 在脱字符^之后再加上一个数字n,表示该指针的第n个父提交。如果一个引用没有这么多个父提交,就会出现引用错误

    $ git show master^2
    
    • 表示显示master分支所指向的提交的第二个父提交的信息。只有master分当前所指的提交对象是由合并得来的时候,该命令才能正确执行。
  3. windowscmd中,^号是一个特殊字符,所以需要使用双引号括起来

    $ git show HEAD^ #ERROR
    $ git show "HEAD^" #OK
    $git show HEAD^^ # OK
    

波浪号(~

  1. 在一个指针之后加上一个~号,也表示该指针指向的提交的父提交

    $ git show master~
    
  1. ~号之后再增加一个数字n,表示该指针当前指向的提交沿着某一路径的回溯的第n个提交

    $ git show master~2
    
    • master的父提交的父提交

提交区间

双点

$ git log <master>..<dev>
  • 选出在<dev>分支上但是不在<master>分支上的提交记录

多点

  1. 在一个分支前面加上^或者--not表示不包含在该分支上的提交

  2. 在分支名前加上^,表示只对其后的第一个分支的否定

    $ git log ^<master> <dev>
    $ git log <dev> ^<master>
    
    • 上面两条命令都表示在<dev>上但是不在<master>上的提交
  3. 使用--not,表示对其后的所有分支的否定

    $ git log --not <master> <dev>
    $ git log <master> --not <dev>
    
    • 这两个命令效果不同
    • 第一个命令表示不在<master><dev>上的提交
    • 第二个命令表示在<master>上但是不在<dev>上的提交

三点

$ git log <master>...<dev>
  • 表示表示存在于<master>或者是<dev>分支上,但是不同时存在于这两个分支上的提交
  • 也就是那些非<master><dev>同时共有的提交

在该命令之后添加一个--left-right选项能够显示每一个提交所属的分支,使得结果更加清晰

$ git log <master>...<dev> --left-right

贮藏

普通贮藏

$ git stash [push]
  • 该命令将工作区和暂存区中的所有没有提交的修改贮藏起来
  • 贮藏之后工作目录和暂存区就会变为干净的状态

贮藏应用

$ git stash apply
  • 将最新的一次贮藏内容应用于当前分支

查看贮藏列表

$ git stash list

应用旧版本的贮藏

$ git stash apply stash@{<n>}
  • stash@{<n>}可以通过查看贮藏列表获得

应用贮藏并且将原本暂存的文件暂存

$ git stash apply --index

删除贮藏内容

$ git stash drop stash@{<n>}

应用贮藏之后删除该贮藏

$ git stash pop

保留暂存区的内容

$ git stash --keep-index

让贮藏包含新建文件

$ git stash --include-untracked/-u

把所有文件(包括被忽略的文件)都贮藏

$ git stash -a/--all

新建一个分支用于应用贮藏

$ git stash branch <branch>

搜索

Git grep

  1. Git中提供了一个grep命令,用于在提交历史、工作目录甚至是索引中查找一个字符串

  2. 该命令支持正则查找

  3. 基本用法

    $ git grep <regex>
    
    • <regex>为匹配字符串
  4. 输出匹配行行号

    $ git grep --line-number/-n <regex>
    
  1. 只输出匹配结果的概略信息

    $ git grep -c/--count <regex?
    
  1. 显示匹配结果的上下文(匹配结果所在的函数或者方法)

    $ git grep -p/--show-function <regex>
    

Git日志搜索

搜索新增或者删除一个字符串的提交日志
$ git log -S <regex>
搜索一行或者一个函数的提交历史
$ git log -L <regex>

END

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339