基础操作
1.添加远程仓库
这里远程仓库以github为例进行演示(github上创建仓库的步骤这里就不再详细说明了)
# 查看本地分支
> git branch -av
detached_temp 713aeaa modify readme
* master f5c2e35 add
# 添加并查看远程分支,地址用的是在github上创建的对应仓库的地址
> git remote add origin git@github.com:xxx/git_learn.git
> git remote -v
origin git@github.com:xxx/git_learn.git (fetch)
origin git@github.com:xxx/git_learn.git (push)
2.将本地仓库推送至远程仓库
使用git push命令推送本地分支到远端,使用方式如下
git push <远程主机名> <本地分支名>:<远程分支名>
# 几种常见的缩写
git push origin test # 等于git push origin test:test
git push origin #等于git push origin 当前分支:追踪分支 #需要为当前分支绑定追踪关系
# 设置追踪关系
> git push --set-upstream origin master #设置本地分支与远程分支的追踪关系
> git branch -vv #查看追踪关系
detached_temp 410c579 flag
* master bf2f40b [origin/master] flag
temp 905f0d9 add aaa
3.拉取远程分支
1.git fetch
git fetch
是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。
git fetch 命令:
$ git fetch <远程主机名> //这个命令将某个远程主机的更新全部取回本地
如果只想取回特定分支的更新,可以指定分支名:
$ git fetch <远程主机名> <分支名>
最常见的命令如取回origin 主机的master 分支:
$ git fetch origin master
2.git pull
git pull
的过程可以理解为:
git fetch origin master //从远程主机的master分支拉取最新内容
git merge FETCH_HEAD //将拉取下来的最新内容合并到当前所在的分支中
git pull 命令:
$ git pull <远程主机名> <远程分支名>:<本地分支名>
例如将远程master分支拉取到本地并与本地master分支合并
$ git pull origin master //可以省略master:master 为 master
3.总结
git pull
包含了git fetch
命令,即git pull = git fetch + git merge
典型场景
1.其他人修改了不同文件
如图,协同场景下,多个人修改同一分支;
当你准备提交你的代码时,如果有人在你拉取代码之后先向远程分支提交了改动,这时在push的时候git通过本地分支和远端分支的commit对比会发现: 本地落后于远端一个版本(也就是commit ID 002这次提交)并且领先于远端一个版本(也就是commit ID 003这次提交)
;
此时是无法将代码push到远端的,需要先使用git pull命令将远端代码拉取并合入你的本地分支(这时会产生commit ID 004),由于修改的是不同文件,因此git可以自动的将代码合并,不会产生冲突
,执行完成后再次push即可顺利推送至远端
2.其他人修改了相同文件不同位置
与上述场景一样,git是按行去进行文件比对的,如果修改的是不同行的内容,git也可以帮你自动合并,不会产生冲突
,因此执行完git pull以后可以直接push至远端
3.其他人修改了相同文件的相同位置(冲突解决)
此场景下由于目标分支和待合入分支修改了同一行内容,git此时无法智能的将代码合并(不知道要保留谁),因此此时会出现冲突
例如此时test 分支的readme文件内容为
## 本地test分支 readme.txt 内容
aaa
bbb
ccc
用户A将其拉取到本地,这时用户B提交他的改动到远端,此时远端内容如下
## 远程test分支 readme.txt 内容
aaa
bbb
ccc user1 edit it!
用户A本地修改readme文件内容并commit
aaa
bbb
ccc user2 edit it!
此时使用git pull会提示冲突,且readme内容如下
aaa
bbb
<<<<<<< HEAD
ccc user2 edit it!
=======
ccc user1 edit it!
>>>>>>> 87285c453d26e4313fd911f08aac6c1471964d99
最终决定保留user2的改动,因此直接修改为
aaa
bbb
ccc user2 edit it!
冲突解决后git add&git commit&git push 三联即可成功推送至远端
4.文件名变更相关
协作开发过程中还有一种可能会遇到的情形,就是文件名变更,关于文件命变更,还可以细分为以下两个子场景:
4.1 文件名和内容变更
如果开发者A修改了index.html为index.htm,你修改了index.html中的文件内容,且A先于你提交,那么这时由于不是fast-forward 你需要先pull再提交代码,此时git会智能的将你们的改动合并
,即pull代码后你会发现文件名已经变更且不影响你对文件内容的变更。
4.2 文件名变更
如果开发者A修改了index.html为index1.html,且你修改同一文件的文件明为index2.html,这是不论你们谁先提交,后提交的一方会遇到冲突,此时pull代码后,git会同时保留index1.html和index2.html,具体删除哪个由开发者自行决定
5.总结
良好的操作习惯为:
git pull
-> 修改代码
-> git commit
-> git pull
-> 解决冲突(如果有) + add&commit
-> git push