Git

Git 详解~

版本控制,团队合作的必备工具

Posted by Wanglizhi on April 24, 2016

能长期在Github活跃,为开源项目做贡献,是程序员学习的最好状态,很难也很简单,是我追求的目标!

有个坑提醒下:jekyll 的date指定的日期比实际时间少8小时

概括

Git是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

在大三之前都是用subversion,目前业界基本都是Git了,学会Git成了开发者的必备技能。

Git常用命令参考(长期更新)

git fetch
git merge origin/master
git mergetool // 解决冲突工具
git reset —hard HEAD~1 // 回退到上个版本
git reset --hard 版本号 // 回退到某个版本
git remote set -url origin URL // 本地修改远程地址

Git 远程操作详解

Git有很多优势,其中之一就是远程操作非常简便。下面将详细介绍5个Git命令:

  • git clone
  • git remote
  • git fetch
  • git pull
  • git push

git clone

git clone支持多种协议地址

$ git clone <版本库的网址>
$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git 
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/

通常来说,Git协议下载速度最快,SSH协议用于需要用户认证的场合。

git remote

Git要求每个远程主机都必须指定一个主机名。git remote命令就用于管理主机名。

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

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

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

删除、添加、重命名远程主机的命令

$ git remote show <主机名>
$ git remote add <主机名> <网址>
$ git remote rm <主机名>
$ git remote rename <原主机名> <新主机名>

git fetch

将远程主机版本库更新取回本地

$ git fetch <远程主机名>
// 默认取回所有分支的更新,也可以指定分支
$ git fetch <远程主机名> <分支名>

在本地主机上要用”远程主机名/分支名”的形式读取。比如origin主机的master,就要用origin/master读取。

git branch命令的-r选项,可以用来查看远程分支,-a选项查看所有分支。

$ git branch -r
origin/master

$ git branch -a
* master
  remotes/origin/master

取回远程主机的更新以后,可以在它的基础上,使用git checkout命令创建一个新的分支。

$ git checkout -b newBrach origin/master

此外,也可以使用git merge命令或者git rebase命令,在本地分支上合并远程分支。

$ git merge origin/master
# 或者
$ git rebase origin/master

git pull

git pull命令的作用是,取回远程主机某个分支的更新,再与本地的指定分支合并。它的完整格式稍稍有点复杂。

$ git pull <远程主机名> <远程分支名>:<本地分支名>

如果合并需要采用rebase模式,可以使用--rebase选项

$ git pull --rebase <远程主机名> <远程分支名>:<本地分支名>

如果远程主机删除了某个分支,默认情况下,git pull 不会在拉取远程分支的时候,删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致git pull不知不觉删除了本地分支。

但是,你可以改变这个行为,加上参数 -p 就会在本地删除远程已经删除的分支。

$ git pull -p
# 等同于下面的命令
$ git fetch --prune origin 
$ git fetch -p

git push

git push命令用于将本地分支的更新,推送到远程主机。

$ git push <远程主机名> <本地分支名>:<远程分支名>
$ git push origin master
// 将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。

如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。

$ git push origin :master
# 等同于
$ git push origin --delete master

如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用--force选项。

$ git push --force origin 

上面命令使用--force选项,结果导致远程主机上更新的版本被覆盖。除非你很确定要这样做,否则应该尽量避免使用--force选项。

参考 Git远程操作详解

Git 使用规范流程

团队开发中,遵循一个合理、清晰的Git使用流程,是非常重要的。

下面是ThoughtBot 的Git使用规范流程。

第一步:新建分支

# 获取主干最新代码
$ git checkout master
$ git pull

# 新建一个开发分支myfeature
$ git checkout -b myfeature

第二步:提交分支commit

$ git add --all // 等于git add . 
$ git status
$ git commit --verbose

git commit 命令的verbose参数,会列出 diff 的结果。

第三步:撰写提交信息

提交commit时,必须给出完整扼要的提交信息

第一行是不超过50个字的提要,然后空一行,罗列出改动原因、主要变动、以及需要注意的问题。最后,提供对应的网址(比如Bug ticket)。

第四步:与主干同步

$ git fetch origin
$ git rebase origin/master

git rebase用于把一个分支的修改合并到当前分支,而那些老的提交会被丢弃。 如果运行垃圾收集命令(pruning garbage collection), 这些被丢弃的提交就会删除.

第五步:合并commit

分支开发完成后,很可能有一堆commit,但是合并到主干的时候,往往希望只有一个(或最多两三个)commit,这样不仅清晰,也容易管理。

$ git rebase -i origin/master

git rebase命令的i参数表示互动(interactive),这时git会打开一个互动界面,进行下一步操作。

第六步:推送到远程仓库

$ git push --force origin myfeature

git push命令要加上force参数,因为rebase以后,分支历史改变了,跟远程分支不一定兼容,有可能要强行推送(实际开发慎用force

第七步:发出Pull Request

提交到远程仓库以后,就可以发出 Pull Request 到master分支,然后请求别人进行代码review,确认可以合并到master。

git merge 对比 git rebase (history)

对于使用git merge来合并所看到的commit的顺序(从新到旧)是:C7 ,C6,C4,C5,C3,C2,C1

对于使用git rebase来合并所看到的commit的顺序(从新到旧)是:C7 ,C6‘,C5’,C4,C3,C2,C1

参考 Git 使用规范流程

git rebase简介(基本篇)