你需要知道的12个Git高级命令

本贴最后更新于 3216 天前,其中的信息可能已经时过境迁

众所周知,Git目前已经是分布式版本控制领域的翘楚,围绕着Git形成了完整的生态圈。学习Git,首先当然是学习Git的基本工作流。相比于SVN等传统版本控制系统来说,Git是专为分布式版本控制而生的强大工具。使用Git时常用的命令有pull、commit、push等,貌似很简单。不过,有时你会遇到合并冲突的情况,Git这时会将冲突标记出来,需要你手工来解决。有时,你会不小心将代码提交到错误的分支上,并且又推送到了远程仓库。还有些时候,你需要切换到不同的分支,但Git却不让你这么做,因为还有未保存的修改。如果需要通过另一个分支的提交来为代码打补丁该怎么做呢?本文就将介绍12个Git高级命令,合理使用这些命令可以大大提升应用Git的效率。

1. 使用rebase而非merge来拉取上游修改

分支合并会被记录为一次合并提交,这种做法是很有意义的。比如说,可以通过这种方式来标识一个新特性被合并到了发布分支中。不过,当多个团队成员工作在一个项目中并使用常规的git pull来同步分支时,提交时间线就会被不必要的合并提交所污染。更好的做法则是使用git rebase将一个feature分支变基到master分支:

$ git checkout feature
$ git rebase master

这么做会将整个feature分支移动到master分支的起点,它会合并master分支上所有新的提交。不过,相比于使用合并提交来说,变基会通过在原来的分支中为每次提交创建全新提交来重写项目历史。变基的主要好处在于你会得到一个更加整洁的项目历史。此外,这里还有关于变基的陷阱的一些讨论。

2. 在执行git rebase后解决合并冲突

正如能力越大责任就越大一样。在执行git rebase时,你可能会遇到合并冲突的情况。合并冲突表示两个提交修改了同一个文件的同一行,Git不知道该应用哪一个修改。这会导致如下所示的错误消息:

Git会为你提供3个选择来修复导致冲突的提交(fa39187):

  • 可以运行git rebase --abort来完全取消变基。这么做会取消变基修改,并将分支置回到执行git rebase之前的状态。
  • 可以运行git rebase --skip来完全忽略该提交。这样,有问题的提交所引入的变化就不会被添加到历史中。
  • 可以使用与合并冲突相同的标准步骤来解决冲突。

3. 临时性保存修改

在工作进行中时,有些东西常常会处于凌乱的状态。如果这时需要切换到不同的分支该怎么办呢?Git是不允许你这么做的,因为还有尚未保存的修改。坦率地说,你并不想将半成品提交上去,后面再来修改。这个问题的解决之道就是使用git stash命令。Stash会接收工作目录的当前状态(比如说,修改了的追踪文件与暂存区的修改等),并将其保存到未完成的修改栈中,这样后面随时可以再来修改。可以通过如下命令来暂存你的工作:

$ git stash
Saved working directory and index state WIP on feature: 3fc175f fix race condition
HEAD is now at 3fc175f fix race condition

现在,工作目录就是干净的了:

$ git status
# On branch feature
nothing to commit, working directory clean

这时就可以安全地切换分支做别的事情了。不过不必担心,暂存的提交依旧还在:

$ git stash list
stash@{0}: WIP on feature: 3fc175f fix race condition

稍后,在回到feature分支后,你就可以取回所有暂存的变更了:

$ git stash pop
On branch feature
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
 modified:   index.html

Dropped refs/stash@{0} (ac2321cc3a33ba712b8e50c99a99d3c20da9d6b8)

关于暂存,还有其他一些选项可用,如下所示:

$ git stash save "describe it"   # give the stash a name
$ git stash clear                # delete a stashed commit
$ git stash save --keep-index    # stash only unstaged files

4. 克隆一个特定的远程分支

如果想要从远程仓库中克隆一个特定的分支该怎么做呢?通常你会使用git clone,不过这么做会将所有其他分支都一并克隆下来。一个便捷的方式是使用git remote add:

$ git init  
$ git remote add -t  -f origin 
$ git checkout 

5. 将cherry-pick远程提交合并到自己的分支中

更有甚者,如果只想将远程仓库的一个特定提交合并到自己的分支中该怎么做呢?可以使用git cherry-pick 来选择给定SHA值的提交,然后将其合并到当前分支中:

$ git cherry-pick 

6. 应用来自于不相关的本地仓库的补丁

如果需要将另一个不相关的本地仓库的提交补丁应用到当前仓库该怎么做呢?答案就是下面这条命令:

$ git --git-dir=/.git format-patch -k -1 --stdout  | git am -3 -k

7. 忽略追踪文件中的变更

如果你和你的同事操纵的是相同分支,那么很有可能需要频繁执行git merge或是git rebase。不过,这么做可能会重置一些与环境相关的配置文件,这样在每次合并后都需要修改。与之相反,你可以通过如下命令永久性地告诉Git不要管某个本地文件:

$ git update-index --assume-unchanged 

8. 每隔X秒运行一次git pull

通常,合并冲突出现的原因在于你正在工作的本地仓库不再反映远程仓库的当前状态。这正是我们为什么每天早晨要首先执行一次git pull的缘故。此外,你还可以在后台通过脚本(或是使用GNU Screen)每隔X秒调用一次git pull:

$ screen
$ for((i=1;i<=10000;i+=1)); do sleep X && git pull; done

9. 将子目录分隔为新的仓库

有时,你可能需要将Git仓库中某个特定的目录转换为一个全新的仓库。这可以通过git filter-branch来实现:

$ git filter-branch --prune-empty --subdirectory-filter  master
# Filter the master branch to your directory and remove empty commits
Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (89/89)
Ref 'refs/heads/master' was rewritten

现在,仓库会包含指定子目录中的所有文件。虽然之前的所有文件都会被删除,但他们依旧存在于Git历史中。现在可以将新的本地仓库推送到远程了。

10. 清理

有时,Git会提示“untracked working tree files”会“overwritten by checkout”。造成这种情况的原因有很多。不过通常来说,我们可以使用如下命令来保持工作树的整洁,从而防止这种情况的发生:

$ git clean -f     # remove untracked files
$ git clean -fd    # remove untracked files/directories
$ git clean -nfd   # list all files/directories that would be removed

11. 将项目文件打成tar包,并且排除.git目录

有时,你需要将项目副本提供给无法访问GitHub仓库的外部成员。最简单的方式就是使用tar或zip来打包所有的项目文件。不过,如果不小心,隐藏的.git目录就会包含到tar文件中,这会导致文件体积变大;同时,如果里面的文件与接收者自己的Git仓库弄混了,那就更加令人头疼了。轻松的做法则是自动从tar文件中排除掉.git目录:

$ tar cJf .tar.xz / --exclude-vcs

12. 查找修改者

最后,如果出现混乱的情况,你一定想要找出是谁造成的。如果生产服务器宕机,那么找到罪魁祸首是比较容易的事情:只需执行git blame。该命令会显示出文件中每一行的作者,提交hash则会找出该行的上一次修改,还能看到提交的时间戳:

$ git blame 

当然,Git命令是非常多的,除了上面介绍的12个重要命令外,相信各位InfoQ读者在日常工作过程中也有自己偏爱且好用的一些命令,不妨以评论的形式与其他读者一同分享。

 

转自: http://www.infoq.com/cn/news/2016/01/12-git-advanced-commands

  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    209 引用 • 358 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
Vanessa
我们终此一生,就是要摆脱他人的期待,找到真正的自己。 昆明

推荐标签 标签

  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 72 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 26 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 664 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    26 引用 • 84 回帖
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 40 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 364 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 18 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    179 引用 • 407 回帖 • 488 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    36 引用 • 37 回帖 • 529 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 334 关注
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    1 引用 • 1 回帖 • 9 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    52 引用 • 190 回帖
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 471 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 4 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 1 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 654 关注
  • 电影

    这是一个不能说的秘密。

    120 引用 • 599 回帖
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 453 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖 • 43 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 536 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 1 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 154 关注