阻止用户查看存储库中的其他分支

时间:2018-01-05 11:28:03

标签: git bitbucket git-branch

我们正在使用Bitbucket和Git。 是否可以设置一个可以在存储库中查看JUST ONE BRANCH的用户,他可以使用哪个?

2 个答案:

答案 0 :(得分:2)

更新

对该问题的评论提出了另一种方法:您可以加密回购中的秘密文件,而不是与承包商共享解密密钥。如果加密是好的,这是一个可行的解决方案,比下面的任何方法更容易。如果我真的是偏执狂,它仍然让我有点不安,因为人们认为加密方案足够安全"受到损害。不过,这是一个选择。

它还提出了另一种方法:

假设你没有在这个回购中使用git lfs。然后你可以使用git lfs来跟踪秘密文件。 (这不是 lfs真正适用的,但请耐心等待。)然后你与承包商分享你的lfs商店,所以承包商应配置他们的repo克隆以使用lfs(或者,如果他们这样做,他们只会在尝试解析秘密文件时遇到错误,这仍然可以。)

这个想法会起作用,因为lfs用一个"指针文件取代了repo中的文件"包含实际文件的SHA-256哈希值。如果无法访问您的lfs存储,则无法通过远程实用的方法从此哈希中推断出实际的文件内容。

问题在于,如果您想将lfs用于其预期目的(管理大型二进制文件),那么您需要共享lfs存储,因此lfs存储无法再隐藏秘密。 (好吧,可能还有一种解决方法,但它又开始变得奇怪了。)即使这样,也可以选择设置自己的干净/涂抹过滤器就像 lfs(替换"无意义的"原始文件的指针等),尽管这更像是一个高级配置要进行整理。

这些解决方案的任何的缺点是git的更改跟踪功能受到阻碍。例如,如果存储的版本被加密或由指针文件替换,则无法直接将此版本的机密文件与该版本的机密文件区分开来。你必须检查两个版本到工作树并在文件系统上区分它们。

无论如何,继续原来的答案......

这根本不是一个容易解决的问题。

MaSiMan所说的或多或少是真的,但并没有解决在fork和原始版本之间持续共享更改的潜在复杂性(不会将秘密文件泄漏到fork中)。当然,你可能已经拥有了秘密文件和一堆历史记录,而且没有时间机器。所以在这种情况下......仍然可行但可能更多参与。

我将逐步介绍使这种方法有效的方法,主要是希望它能说服你这不实用。因此,如果您想接受我的话,请跳到下一个横向规则,之后我会提出一个您可能不会喜欢的替代方案(但这仍然远远超过了这种方法)

所以你至少需要两个回购。我不知道任何允许用户级别控制阅读特定分支的托管软件,因此您需要一个承包商可以完全阅读的回购。

首先创建一个可以安全分享的分支。听起来你有一个计划,但要小心:如果计划是创建分支,删除秘密文件,然后提交到分支......

x -- x -- x -- A -- x -- x <--(master)
                \
                 \ # rm secret-file
                  \
                   B <--(contractor)

... contractor分支不是&#34;清洁&#34;你可能会想,因为Acontractor分支上的master一样多。因为它是git clone --depth=1 -b contractor url/of/origin &#34;。

要做到这一点,你的第二个回购必须是一个浅层克隆。

origin

您的托管软件可能无法提供&#34;浅叉&#34;,但只要它将托管浅层回购,您至少可以手动创建克隆并将其作为承包商托管git filter-branch回购。然后你只需要在回购之间协调推/拉。这可能取决于托管软件,但最糟糕的情况是你可以设置浅回购的本地克隆,原始回购作为第二个远程。

如果您希望承包商拥有更完整的历史记录(除秘密文件之外的所有内容),您可以使用git checkout master git checkout -b clean-master git filter-branch index-filter='git rm --cached --ignore-unmatch -- path/to/secret-file' -- clean-master 来生成已清理的历史记录。

A -- B -- C <--(master)

A' -- B' -- C' <--(clean-master)

现在你有(在一个回购中)

clean-master

其中秘密文件在clean-master的历史记录中无处可去。因此,您创建一个仅包含 git clone --single-branch -b clean-master url/of/origin 分支

的克隆
git gc --aggressive --prune=now

现在要超偏执,我应该指出这个应该创建一个&#34; clean&#34;克隆,但可以想象一个git实现可以采取快捷方式处理包文件,以便信息&#34;泄漏&#34;从原来的分支到新的回购。如果这让您担心,您可以检查新仓库中是否存在密码文件(即在原始仓库中找到其BLOB ID,并查看克隆是否通过这些ID知道任何对象),或者可能只是强制垃圾收集器在克隆中运行

git checkout master
git tag shared-to-clean-master
git checkout clean-master
git tag shared-to-master

应该这样做,因为新鲜克隆还没有任何reflog历史记录。

无论如何,你可以在你的托管软件中设置这个新的仓库(它甚至不再需要忍受浅层克隆),而且你将不得不弄清楚如何推/拉两者之间。

无论采用哪种解决方案,还有一个关于如何在&#34; clean&#34;之间分享变化的问题。分支和常规分支,不会意外泄漏秘密文件。任何在两者之间合并的企图都会有陷阱,而且无论如何都是&#34; clean&#34; branch永远不能包含这样的合并。使用合并可能并不实际。

当你看到我建议的东西时,你可能会想知道这可能是什么?更实用&#34;替代...就像我说的,这不是一个容易解决的问题。

所以你可能不得不通过变基来回分享变化 - 这不是我通常会推荐的,因为这意味着你不断创建并行提交,并做出同样的改变&#34;在两个不同的分支。这也意味着你必须使用标签(或一些类似的机制)来跟踪每一方的哪些变化已经分享给另一方。

所以无论你用哪种方法创造&#34;清洁&#34;分支,最初所有更改都存在于两个分支中。所以标记两个头。

... A -- B -- C -- D <--(master)
    ^shared-to-clean-master

... A' -- X -- Y -- Z <--(clean-master)
    ^shared-to-master

现在你的脏分支正在进行一些工作,承包商做了一些工作,推到你的干净分支,最终你有

git checkout clean-master
git checkout -b clean-to-dirty-temp
git rebase --onto master shared-to-master clean_to_dirty_temp
git checkout master
git checkout -b dirty_to_clean_temp
git rebase --onto clean_master shared-to-clean-master dirty_to_clean_temp

不,你们两者之间的变化。

                     X' -- Y' -- Z' <--(clean-to-dirty-=temp)
                    /
... A -- B -- C -- D <--(master)
    ^shared-to-clean-master

                      B' -- C' -- D' <--(dirty-to-clean-temp)
                     /
... A' -- X -- Y -- Z <--(clean-master)
    ^shared-to-master

虽然您可能会认为&#34;我只是编写脚本#34;但请记住,rebase操作可能会产生冲突。特别是,如果&#34;脏&#34; side包含对机密文件的更改,然后您想要那些冲突,以便您可以通过确保文件不会在&#34; clean&#34上弹出来解决冲突;分支。

所以这会产生

master

现在您想要推进clean-mastergit checkout master # then either... git merge clean-to-dirty-temp # ... which should fast-forward, or git merge --squash clean-to-dirty-temp # and finally git branch -d clean-to-dirty-temp git tag -f shared-to-clean-master 引用,可能使用快进或压缩合并(取决于您是否要保留原始提交粒度)。

git checkout clean-master

# then either...
git merge dirty-to-clean-temp
# ... which should fast-forward, or
git merge --squash dirty-to-clean-temp

# and finally
git branch -d dirty-to-clean-temp
git tag -f shared-to-master

当然在另一边

... A -- B -- C -- D -- X' -- Y' -- Z' <--(master)
                                    ^shared-to-clean-master

... A' -- X -- Y -- Z -- BCD <--(clean-master)
                           ^shared-to-master

假设您快速转发脏分支并压扁干净的分支。然后这将离开你

git diff master clean-master

你应该能够验证

clean-master

仅显示git checkout shared-to-master git checkout -b clean-to-dirty-temp git merge --squash clean-master # and proceed with the rebase from here 中缺少密码文件。冲洗并重复。

哦,除了任何一个分支和合并,然后rebase变得更复杂。事实上,如果任何一方做过“邪恶的合并”,你就会陷入一些真正的麻烦。这可能意味着,如果任何一方确实包含分支和合并,您需要在重新定义来回变化之前简化历史记录。有很多方法可以做到这一点,但它是另一层复杂性。举个例子

{{1}}

当然,为了防止分支机构发生分歧,这是一个比它已经保证的更大的混乱,你必须经常这样做。

好的,让我们面对现实:上述解决方案很糟糕。怎么办?

嗯,您基本上需要从回购中删除秘密文件,以便您和承包商可以共享相同的持续更改历史记录。

但是你需要那个文件,你可能需要它来进行版本协调。

因此,只为你的眼睛提供秘密文件自己的回购。然后创建一个第三个repo,它不包含自己的文件,但引用共享repo和&#34;秘密文件&#34; repo as submodules。

答案 1 :(得分:0)

针对您的潜在解决方案可能是{<3}}您的存储库之后添加机密文件。然后外包商可以在分叉上工作,您可以将他的更改恢复到您的主仓库中。