github:“链接”组织的私人回购协议
我有一个 github 私人存储库,我一直在其中与其他一些(私人)合作者合作。我们称之为repo-a。
一位客户刚刚将我添加到他们的组织帐户中。我基本上需要与该组织中的其他开发人员共享我的repo-a。我不确定“分享”在这里是否是正确的术语;也许我需要“复制”?我该怎么做呢?
我希望有人能够提供帮助的更重要的问题是,我不希望本组织看到我的私人合作者所犯下的历史。但是,希望我能够轻松地将repo-a中的最新代码“推送”给组织(我仍然计划与repo-a私下合作)合作者)。这合理可能吗?
I have a github private repository, in which I have been working with a few other (private) collaborators. Let's call it repo-a.
A client just added me to their Organization account. I need to essentially share my repo-a with other developers in that Organization. I am not sure whether "share" is the right term here; maybe I need to "copy"? How do I go about doing this?
The more important issue that I hope someone can help is I don't want the Organization to see the history committed by my private collaborators. But, hopefully, I will be able to easily "push" the latest code in repo-a to the Organization (I am still planning to work privately with the repo-a collaborators). Is this reasonably possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
简短回答:不,这不太可能。
您在这里会给自己带来很多麻烦。如果您提供给他们的历史记录不包含实际的历史记录,那么根据定义,您没有记录他们的版本包含哪些提交。无论如何,您永远无法从包含“私有”提交的分支推送到不包含“私有”提交的分支。您基本上要求拥有如下所示的历史记录:
其中 ABCD 是包含提交 A、B、C 和 D 的更改的提交,类似地 EFGH 隐藏了 E、F、G 和 H。您可以这样做使用 git checkout public-branch; git merge --squash 私人分支。挤压合并执行合并,然后将其记录为常规提交,即没有合并的分支作为父分支。只要您在合并时非常小心,此选项可能适合您。尽管如此,这仍然是一种痛苦。 (请注意,合并 Y 和 Z 会导致私有存储库中的重复提交,ABCD 与 ABCD。这很丑陋,但比替代方案更好,后者是完全不同的历史记录。)
因此,无论如何,您的历史记录都会出现分歧。最好的情况可能是您使用标签来帮助自己跟踪事物。例如,您可以将提交
D
标记为private-0001
,将ABCD
标记为public-0001
,commit < code>H 为private-0002
并将EFGH
提交为public-0002
。这至少可以让你对不同的历史如何联系在一起有一些记录。 您永远无法真正将任何私有提交合并到公共分支中,因为提交会带来它们的祖先。所以我建议寻找另一种方法。有多种选择,具体取决于您希望这些贡献保持私密的原因:
放弃您的计划,并将私人贡献者公开。
让私人贡献者以您的名义或使用假名进行提交。 (让他们在此存储库的 .gitconfig 中设置
user.name
和user.email
。)如果您只想让他们保持匿名,这将是足够且轻松。做到一半。回顾第一个图表,在进行挤压合并后,将所有私人贡献者重置到该点(重新设置他们可能拥有的任何其他分支的基础)。每次公开发布时,您基本上都会抛弃私人提交,并将压缩合并提交视为新的事实。这需要你保持警惕,确保其他贡献者按照要求行事,但这会让你免受所有疯狂历史的包袱。 (如果有人重置失败,这是可以修复的。假设他们在提交
D
之上提交了E
而不是提交ABCD
。他们可以使用git rebase --onto commit-ABCD commit-D
将其分支移植到其所属的位置。)您的历史记录最终将如下所示:<前><代码>- W - X - ABCD ------------------ Y - Z - EFGH - ...
\ \
A - B - C - D(废弃) E - F - G - H(废弃)
这样做的好处是,您永远不会有任何跨越大量历史的可怕的粗糙合并,并且您不会以无关合并或重复提交的形式拖拽任何包袱。如果你公开发布私人贡献的频率足够低,那就不会那么痛苦。如果你小心的话,你甚至可以让事情变得有点异步,例如:
<前><代码>- W - X - AB - X - CD - Z - ...
|\
| A - B(废弃)
\
C - D(废弃)
要非常非常小心地跟踪您合并的内容。除了我之前讨论的标记之外,您还可以让您的压缩合并提交包含短 SHA1 列表和合并提交中的提交主题。
Short answer: no, it's not reasonably possible.
You're setting yourself up for a lot of trouble here. If the history you give them doesn't contain the actual history, then by definition you have no record of what commits their version includes. No matter what, you will never be able to push from a branch that includes the "private" commits to one that doesn't. You're basically asking to have history that looks like this:
where ABCD is a commit containing the changes of commits A, B, C, and D, and similarly EFGH hides away E, F, G, and H. You can do this using
git checkout public-branch; git merge --squash private-branch
. A squash merge performs the merge, then records it as a regular commit, i.e. without the merged branch as a parent. This option might work for you, as long as you're very careful with the merging. It's still a pain, though. (Note that merging Y and Z results in duplicate commits in the private repo, ABCD vs A-B-C-D. This is ugly, but better than the alternative, which is completely divergent history.)So no matter what, your history will diverge. The best case is probably for you to use tags to help yourself keep track of things. For example, you could tag commit
D
asprivate-0001
and commitABCD
aspublic-0001
, commitH
asprivate-0002
and commitEFGH
aspublic-0002
. That would at least let you have some record of how the separate histories are tied together. You can never actually merge any of the private commits into the public branch, since commits bring with them their ancestors.So I'd recommend finding another way. There are several options, depending on your reasons for wanting these contributions kept private:
Abandon your plan, and make the private contributors public.
Have the private contributors commit in your name, or using fake names. (Have them set
user.name
anduser.email
in the .gitconfig of this repository.) If all you're trying to do is keep them anonymous, this would be sufficient and painless.Do it halfway. Looking back at the first diagram, after you do your squash merges, have all the private contributors reset to that point (rebasing any other branches they might have). Every time you publicly publish, you essentially throw away the private commits, and regard the squash-merge commit as the new truth. This will require vigilance on your part, making sure the other contributors do what's required, but it would spare you the baggage of all that crazy history. (If someone fails to reset, it is fixable. Suppose they made commit
E
on top of commitD
instead of commitABCD
. They could usegit rebase --onto commit-ABCD commit-D
to transplant their branch where it belongs.) Your history would end up like this:The benefit of this is that you never have any horribly gnarly merges spanning a lot of history, and you don't drag around any baggage in the form of extraneous merges or duplicate commits. If you publicly publish the private contributions infrequently enough, it wouldn't even be that painful. You could even let things get a little asynchronous if you're careful, for example:
Just be very, very careful to keep track of what you've squash-merged. Besides tagging as I discussed earlier, you could also have your squash-merge commits include a list of short SHA1s and commit subjects from the merged commits.
Git 存储库带有其所有历史记录。每次。您可以通过删除存储库中的 .git/ 文件夹,然后再次运行 git init 来“导出”存储库的当前状态。这将重置您的历史记录,尽管此时它将是一个完全不同的存储库。
假设您这样做,那么您可以将这个新存储库推送到该组织帐户上的存储库,并且本质上是从旧存储库的快照开始。
希望我正确理解你的问题。
A Git repository comes with all of its history. Every time. You could "export" the current state of your repository by deleting the
.git/
folder from it, then runninggit init
again. This would sort of reset your history, though it would be a completely different repository at this point.Assuming you do that, you could then just push this new repository to a repo on that organization account and be essentially starting from a snapshot of your old repository.
Hope I understood your question right.
我最终创建了一个新的存储库 repo-b 并将其与组织帐户同步。为了将新的更改从repo-a“合并”到repo-b,我使用了
rsync
命令。作为参考,请参阅此已接受的答案以获取确切的命令。然后取决于我的纪律/流程何时更新组织存储库。我可以在每次 repo-a 中有新提交时进行同步,或者等到有几个提交时进行同步(本质上就像挤压合并)。这样,Org 帐户就可以看到我的提交历史记录,同时让我的私人协作者保持匿名。
I ended up creating a new repo repo-b and sync it with the Organization account. To "incorporate" the new change(s) from repo-a to repo-b, I use the
rsync
command. For your reference, see this accepted answer for the exact command.It then depends on my discipline / flow when to update the Org repo. I could sync each time there is a new commit in repo-a or wait until there are several of them (essentially like squash merge). This way, the Org account can see the history of my commits while keeping my private collaborators anonymous.