当进行Git远程操作的时候,有两个概念需要掌握:
跟踪分支 -- tracking branch
跟踪远程分支 -- remote tracking branch
那么在Git本地操作中,分支只是指向某个commit对象的引用,那么跟踪分支和远程跟踪分支在本地仓库中具体又是指什么呢?
上图中,https://yourrepohost/project.git是远程仓库,此时远程master分支指向版本C2
git clone https://yourrepohost/project.git是将远程仓库clone到本地形成local repo,此时会形成一个origin/master的引用,这个origin/master就是我们所说的远程跟踪分支,是用户只读的。同时还会根据origin/master生成一个本地的master分支,同样也是指向C2,这个master分支就是跟踪分支,是用户可写的。
那么用户只读,用户可写又是什么意思呢?下面先来看一张图
当添加一个本地提交C3时,本地的master也将移向C3,当git push到远程仓库的时候,远程仓库的master也将移动到C3,此时,git push 还会做一件事情,他会将本地的origin/master移动到C3,本地仓库是不能对origin/master进行操作的
其实这个用户只读还有另外一层解释,在git本地操作中,使用git checkout master切换到master分支,其实是将HEAD引用指向了master分支,那么如果使用git checkout origin/master,HEAD引用是不会指向origin/master的,在这样的状态下,如果做了一些提交,并切换回master分支,然后再切换回origin/master,那么上次提交的文件将不会存在,除非使用reflog(维护HEAD引用的变化历史)去寻回。
除了 git clone 是从服务器初次获取数据之外,我们还可以通过 git fetch 和 git pull 从服务器获取数据。git fetch相当于从远程获取最新版本到本地,但不会自动merge,而git pull相当于从远程获取最新版本并merge到本地,git pull命令相当于git fetch和git merge。而在实际应用中,git fetch是更安全一些的,因为在merge前,我们还可以查看更新的情况,然后再决定是否要合并。
下面来看几个场景:
场景1 :使用git clone克隆github上的远程master分支到本地后,再对github上的远程master分支上的文件做修改,此时如果想要从本地将远程master分支上的内容获取到,就可以使用 git fetch 去拉取数据
git fetch后查看历史信息,可以看到,此时origin/master已经移动到最新的版本,而本地master/HEAD还在原来的位置
那么此时就要使用 git merge origin/maste r 来合并origin/master 让本地master/HEAD也移动到最新的版本
场景2 : 假设我在本地修改了remote.txt的文件,而另外一个人也对remote.txt做了修改并git push了到了远程分支,此时我在本地如果使用git push的话是不行的,因为远程分支上有一些文件的修改是你本地所没有的,如果强制push的话,就会覆盖掉远程分支上的文件,所以在这样的情况下就必须先git pull(git fetch+git merge)从远程获取最新的数据到本地
但此时可以看到,本地和远程都对同一文件做了修改,因此产生了冲突,所在在merge的时候会提示处理冲突
<<<<<<< 和 =====之间的内容是本地所做的修改, ===== 和 >>>>>>之间的内容是远程分支所做的修改
将不需要的内容删除后再进行git add - git commit - git push操作就可以将内容推送到远程仓库中.
如果git push后还想对此次最新的提交打上tag,可以使用git tag -a v1 -m "tag for v1"给此次提交打上带注解的tag,git push是默认不将tag 推送到远程分支上的,所以这里使用git push --tag对远程分支上的版本打上tag
场景3 :假设本地和远程仓库都有一个feacher分支,我们想要删除该怎么做?
先切换到除feacher分支之外的其他分支,比如master分支,然后使用git branch -d feacher先删除本地的feacher分支,然后使用git push --delete origin feacher删除了远程仓库中的feacher分支
还有另外一种方法也可以删除远程仓库中的分支, 使用git push origin :feacher去删除,这条命令的意思,就是在远程仓库中使用一个空的分支替代feacher分支,注意origin后面先是一个空格然后再跟上冒号