繁体   English   中英

Git:--force-with-lease 和多个 pushurls

[英]Git: --force-with-lease and multiple pushurls

我有一个在 3 台主机上镜像的远程origin的 git 存储库。

$ git remote -v
origin  git@github.com:username/repo.git (fetch)
origin  git@github.com:username/repo.git (push)
origin  git@gitlab.com:username/repo.git (push)
origin  git@bitbucket.org:username/repo.git (push)

一切都在 commit A 处

$ git rev-parse HEAD
A

$ cat .git/refs/remotes/origin/master
A

我提交B并推送它。 现在每个人都在提交B

$ git push origin master
To github.com:username/repo.git
   A...B             master -> master
To gitlab.com:username/repo.git
   A...B             master -> master
To bitbucket.org:username/repo.git
   A...B             master -> master

$ git rev-parse HEAD
B

$ cat .git/refs/remotes/origin/master
B

现在我注意到最后一次提交中有一个错误,所以我修复它并修改提交。 这使我与遥控器不同步。

$ git rev-parse HEAD
C

$ cat .git/refs/remotes/origin/master
B

我喜欢避免盲目地--force推送,所以我使用--force-with-lease ,但这以一种有趣的方式失败了。

$ git push --force-with-lease origin master
To github.com:username/repo.git
 + B...C             master -> master (forced update)
To gitlab.com:username/repo.git
 ! [rejected]        master -> master (stale info)
To bitbucket.org:username/repo.git
 ! [rejected]        master -> master (stale info)

问题是,-- --force-with-lease只会在远程 ref 与我上次与它通信时处于同一提交时才考虑推送安全,并且我的本地记录了.git/refs/remotes/origin/master中该提交的 sha1 .git/refs/remotes/origin/master 第一个镜像 (GitHub) 更新后,git 将我本地的远程引用更新为提交C ,导致对 GitLab 和 Bitbucket 的推送尝试失败,因为我们现在期望它们处于提交C

我想弄清楚这一点,所以首先我强制 GitHub 镜像返回提交B

$ git push origin +B:refs/heads/master
To github.com:username/repo.git
 + C...B             B -> master (forced update)
Everything up-to-date
Everything up-to-date

现在我需要更具体地说明我希望遥控器进行哪个提交以进行推送。 该文档说您可以使用--force-with-lease=<refname>:<expect>准确指定要更新的引用,以及您期望它当前处于什么提交,所以我尝试这样做。

$ git push --force-with-lease=origin/master:B origin master
To github.com:username/repo.git
 ! [rejected]        master -> master (non-fast-forward)
To gitlab.com:username/repo.git
 ! [rejected]        master -> master (non-fast-forward)
To bitbucket.org:username/repo.git
 ! [rejected]        master -> master (non-fast-forward)

显然我做错了什么。 也许我弄错了<refname> 我觉得我很亲近。 我错过了什么?

非常有趣的问题! 我已经尝试过并成功地在这些测试存储库中使用 Git 2.11.0 重现了您所描述的内容:

通过使用以下表单,我能够成功地将--force-with-lease推送到两个远程 URL:

git push --force-with-lease origin +master

注意分支名称前的+号。 这是输出:

$ git push --force-with-lease origin +master
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 232 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To github.com:hkdobrev/git-test.git
 + 099b95f...08c7548 master -> master (forced update)
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 232 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To github.com:hkdobrev/git-test2.git
 + 099b95f...08c7548 master -> master (forced update)

git-push (1)手册页:

请注意,-- --force适用于所有被推送的引用,因此将它与push.default设置为匹配或使用remote.*.push配置的多个推送目的地一起使用remote.*.push可能会覆盖当前分支以外的引用(包括本地引用)严格落后于他们的远程对手)。 要强制只推送到一个分支,请在 refspec 前面使用+进行推送(例如git push origin +master强制推送到master分支)。 有关详细信息,请参阅上面的<refspec>...部分。

我想出的是

git push --force-with-lease=`git rev-parse --abbrev-ref @{u} | sed 's![^/]*/!!'`:@{u}

哪里

  • git rev-parse --abbrev-ref @{u} | sed 's![^/]*/!!' 获取远程分支名称(不带远程名称)
  • @{u}是我们期望远程分支所在的提交

我还按照Haralan Dobrev 的建议尝试了+规范,但能够使用它覆盖更改。 因此,我认为+规范应该在这里使用,因为它等于法向力 push

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM