同步
git remote
git remote
列出所有的远程连接
git remote -v
列出所有的远程连接及其网址
git remote add <name> <url>
创建一个新的远程连接,之后就可以在git命令中使用指定的名称来指代其url。
git remote rm <name>
删除某个远程连接
git remote rename <old-name> <new-name>
重命名一个连接
Git是以每个开发者都有独立的开发环境为理念设计的,所以仓库之间不会自动传递信息,需要手动去pull和push。所以git remote
充当的是一种把仓库网址映射成某个名称,以便在git命令中使用的角色。
当我们使用git clone
命令的时候,会在拷贝远程仓库代码的同时也建立名为origin的连接指向远程仓库,方便我们pull或push代码。这也是为什么大多数基于git的项目都会把中央仓库叫做origin的原因。
两种最常用的引用远程仓库的方法是通过HTTP和SSH协议。HTTP的连接允许匿名的只读权限,通常无法提交commit到一个HTTP仓库。
http://host/path/to/repo.git
要拥有读写权限的话,就要使用SSH连接
ssh://user@host/path/to/repo.git
此时需要一个有效的SSH账号或者其他认证方法来进行连接。
可以添加其他团队成员的仓库,对于大工程里的小组来说很有用
git remote add john http://dev.example.com/john.git
git fetch
git fetch
命令把远程仓库的commit导入到本地仓库,导入的commit是保存到一个单独的远程分支,而不是目前的正常本地分支,因此可以先查看一下代码再决定要不要合并到项目中。
git fetch <remote>
从指定仓库中取回所有分支,也就会下载所有对应的commit和文件。
git fetch <remote> <branch>
只取回某个特定的分支。
远程分支和本地分支是一样的,只不过远程分支里面保存的是从他人仓库取回来的commit。可以像普通分支一样checkout远程分支,此时会跟checkout一个旧的commit一样处于detached HEAD的状态。可以把远程分支看做是一个只读分支,要查看远程分支的话,只需要在git branch
命令加上-r标志即可,远程分支会自带所属仓库名的前缀,比如说:
git branch -r
# origin/master
# origin/develop
# origin/some-feature
可以用一般的git checkout
和git log
命令去查看远程分支。如果决定要合并到本地分支,可以使用git merge
命令。git pull
就是git fetch
和git merge
的快捷合并操作。
git pull
git pull <remote>
取回当前分支的远程仓库代码,并直接合并到本地分支,等效于
git fetch <remote>
git merge origin/<current-branch>
git pull --rebase <remote>
与上面操作一样,区别在于使用的是rebase命令去合并到本地仓库而不是merge命令。
git push
git push <remote> <branch>
pull request
分支
git branch
git branch
列出仓库的所有分支
git branch <branch>
新建一个分支,并不会切换这个分支
git branch -d <branch>
安全删除某个分支,如果这个分支有未合并的修改,就无法删除掉。
git branch -D <branch>
强制删除某个分支,即使有未合并的修改。
git branch -m <branch>
重命名当前分支
branch只是对于commit的引用,并不会改变仓库内容,调用git branch crazy-experiment
命令只是创建一个新的指针,如下图所示:
git branch <branch>
只会创建分支,还需要checkout命令才能切换到新分支。
如果要删除分支可以通过
git branch -d crazy-experiment
如果该分支还没有合并就会报错,如果确实要强制删除,那就要使用
git branch -D crazy-experiment
git checkout
git checkout
命令可以在branch之间切换
git checkout <existing-branch>
切换到已有分支
git checkout -b <new-branch>
创建并切换到新分支
git checkout -b <new-branch> <existing-branch>
在指定分支的基础上创建并切换到新分支
Detached HEADs:HEAD是Git用来指代当前snapshot的说法,所以git checkout
命令实际上是把HEAD更新到指向某个commit或者分支。
如果HEAD是指向分支的,默认就是指向分支第一个commit,此时是attached HEAD状态;如果HEAD是指向某个以往的commit,就是detached状态
detached状态表示目前进行的操作是脱离于项目目前的开发进度的,如果你做出修改,然后切换到其他分支后想要把detached状态下的修改合并进去,是做不到的,因为detached状态下的修改不属于任何一个分支。
所以如果只想要查看commit内容的话,detached状态是没有影响的,但是如果想要进行修改,就要在attached状态下才有用。
git merge
git merge
命令是把指定分支合并到当前分支,当前分支会被更新,指定分支不受影响。所以一般可以通过git checkout
切换到某个主要的分支,然后通过git merge
合并某个其他分支的内容到这个分支,然后通过git branch -d
来删除那个其他分支。
git merge <branch>
合并指定分支到当前分支,Git自动决定合并算法。
git merge --no-ff <branch>
合并指定分支到当前分支,并且总是产生一个merge commit,可以用来记录进行过的merge。
合并方式有很多种,包括快进合并和三路合并。
快进合并:当前分支到目标分支是直线相通的,合并的话只要把当前分支的尾端移动到目标分支即可,如下图所示
然而如果当前分支与目标分支不在同一条线上,那就没办法快进合并了,只能通过三路合并,三路合并通过三个commit来生成最终的merge commit
对于小的特性添加或者bug修复,可以通过rebase的方式来达到满足使用快进合并多个条件。
对于开发周期较长的特性添加可以用三路合并,产生的合并commit可以作为这两个分支合并的标志。
解决冲突
如果要合并的两个分支都修改了同个文件的同个地方,那就没办法进行合并了,只能先解决冲突。
git解决冲突的流程仍然是编辑/组织/提交。当我们碰到一个合并冲突的时候,可以通过git status
查看哪些文件冲突了:
# On branch master
# Unmerged paths:
# (use "git add/rm ..." as appropriate to mark resolution)
#
# both modified: hello.py
#
然后就可以去修改冲突的文件,再对冲突的文件调用git add
命令,然后调用git commit
去生成merge commit。
合并冲突只可能发生在三路合并当中,快进合并不会发生冲突。
以下为一个快进合并的例子:
# Start a new feature
git checkout -b new-feature master
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Merge in the new-feature branch
git checkout master
git merge new-feature
git branch -d new-feature
以下为三路合并的例子:
# Start a new feature
git checkout -b new-feature master
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Develop the master branch
git checkout master
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to master"
# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature
三路合并的情况是主分支和子分支都同时进行开发,比如下面
# Start a new feature
git checkout -b new-feature master
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Develop the master branch
git checkout master
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to master"
# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature
如果是小的特性开发,建议用rebase然后merge进行快进合并,可以避免太多的commit弄乱项目记录。
工作流程分析
特性分支工作流
特性分支工作流的核心就是特性,所有的新特性开发都必须要在专门的分支上开发,开发完成再合并到主分支上。