同步GIT仓库的操作 -- push命令
git push
命令用于向远程仓库上传本地仓库的内容。push操作就是将本地的commit打包上传到远程仓库中。与之对应,git fetch
操作向本地分支导入commits,push
操作则向远程分支导出commits。远程分支通过之前文章中提到的git remote
命令进行配置。push
操作有可能会覆盖远程的变更,因此操作时需要谨慎行事。关于这个话题下面会有更详细的讨论。
Git push用法
git push <remote> <branch>
上面的命令会将特定的分支推向远程仓库,同时push的还有分支中包含的commits以及git内部对象。这将会在远程仓库中创建特定分支。为了避免这次推送覆盖远程仓库的commits,当其相对于远程仓库的对应分支不能进行快速前进(non-fast-forward)合并时,Git则不允许这次推送。
git push <remote> --force
与前一条命令相同,但是当遇到不可快速前进的合并时,此次推送仍将强制进行。因此,除非你真的很清楚自己在做什么,否则不要使用--force
选项。
git push <remote> --all
将本地所有分支都推送给特定的远程仓库。
git push <remote> --tags
当使用--all
选项推送所有本地分支时,tags并不会被自动推送到远程仓库。因此使用--tags
选项来向远程仓库推送所有本地tags。
关于Git push的讨论
git push
最常用的场景是将本地的修改发布到中心仓库。对本地仓库的内容进行修改之后,执行push
操作以便向其他团队成员共享这些修改。
上面的图例展示了当本地的main
分支的更新比中心仓库的main
分支超前时,执行git push origin main
命令向中心仓库发布这些更新的状况。请注意观察,在本地执行git push
命令推送到远程仓库,本质上和在远程仓库执行git merge main
的效果是一致的。
Git push和同步仓库
git push
命令是Git同步流程中很多组件之一。通过git remote
命令配置远程仓库之后,使用git提供的这一组同步命令对配置之后的远程仓库分支进行操作。git push
命令可以被看作是上传commits,相反git fetch
和git pull
命令则可被看作是下载操作。一旦版本更新被上传或者下载操作同步之后,在相应的仓库内就可以使用git merge
命令来集成这些更新。
强制push
当Git发现push操作会覆盖中心仓库的提交历史,从而导致不能快速前进(non-fast-forward)的合并时会阻止这次操作。因此当远程的提交历史已经和你本地的提交历史发生偏离,你需要先从远程仓库使用git pull
命令拉取最新的变更,并将它们git merge
到本地,然后再进行git push
操作。
--force
选项会无视上述行为,并且强制让远程仓库分支匹配本地分支,具体的方式是删除上次同步远程仓库之后,在远程仓库发生的所有变更。只有在一种场景下需要使用--force
进行push操作,那就是当你发现你刚刚的提交不太对,于是马上使用git commit --amend
进行了修改,或者是使用可交互式rebase命令之后。但仍然需要注意一点,在你使用--force
选项之前,请一定确定你的其他团队成员没有pull过刚才的那些提交。
示例
默认git push
以下示例描述了一套向中心仓库发布本地仓库变更的标准流程。首先,通过git fetch
同步中心仓库main分支在本地的副本,以确保本地副本是最新的,之后通过git rebase
操作将分支的修改变基到远程main分支的提交历史之上。可交互的rebase
操作(rebase -i)同时也是在分享给其他团队成员之前,清理本地commit记录的好机会。紧接着,git push
命令将所有本地的提交都发送向中心仓库。
git checkout main
git fetch origin main
git rebase -i origin/main
# Squash commits, fix up commit messages etc.
git push origin main
由于我们已确保本地的main分支是最新版本的,因此push
操作是能够快速前进的。此时git不会阻止push操作。
修正之后的force push
git commit
命令接受--amend
选项,这一操作可以用来修改上一次的提交。类似这样的提交通常会修正并更新commit message,或者增加新的修改。一旦一次commit被修正之后,git push
会直接失败,因为Git认为修正之后的commit与远程仓库的commit发生了偏离。此时--force
选项就需要粉墨登场了。
# make changes to a repo and git add
git commit --amend
# update the existing commit message
git push --force origin main
上面的示例刚刚执行过一次commit并推送给了远程仓库。之后的git commit --amend
命令用来更新上一次提交。修正之后的commit需要使用--force
选项才能推送到远程仓库。
删除一个远程分支或者tag
有时为了清理仓库或者更好的组织分支结构,需要对分支进行删除操作。要想完全删除一个分支,不仅要在本地删除,还要在远程同步删除。
git branch -D branch_name
git push origin :branch_name
上面的命令首先删除了名为branch_name的远程分支,然后使用git push
将这次删除同步给远程仓库。注意这一push
操作中,会在分支名称前加一个 :前缀,以便通知远程仓库删除远端的同名本地分支。