简体   繁体   English

git如何在不同的分支中保持不同的配置文件?

[英]git how to keep a config file different in different branches?

Allow me phrase my attempt first.请允许我先说出我的尝试。 Let say I have two branch, Alice1 and Alice2.假设我有两个分支,Alice1 和 Alice2。 Alice1 has it's own server and Alice2 has his own too. Alice1 有自己的服务器,Alice2 也有自己的服务器。 I want to be able to checkout to Alice1, writing my code, then test it on its own server by pushing the code directly using the URL that is saved in the URL config file so it has to stay in local.我希望能够结帐到 Alice1,编写我的代码,然后通过使用保存在 URL 配置文件中的 URL 直接推送代码在自己的服务器上测试它,因此它必须留在本地。 Alice2 has its own server also, if the code is tested fine on Alice1, I will checkout to Alice2, and sync with Alice1, then push it on Alice2's server. Alice2 也有自己的服务器,如果代码在 Alice1 上测试良好,我将结帐到 Alice2,并与 Alice1 同步,然后将其推送到 Alice2 的服务器上。 Sometimes I want Alice1 and Alice2 have independent testing environment so they can be seperate until I want to merge them.有时我希望 Alice1 和 Alice2 有独立的测试环境,这样它们就可以分开,直到我想合并它们。

I have been researching this for a long time but still not finding a reliable answer.我已经研究了很长时间,但仍然没有找到可靠的答案。 The most popular solution is using .gitattribute and do merge=ours but it has cons that git will sometimes ignore them in forwarding.最流行的解决方案是使用 .gitattribute 并执行 merge=ours 但它的缺点是 git 有时会在转发时忽略它们。 I also tried checkout file while merging, but this only works in one merge instead of every merging.我也在合并时尝试了结帐文件,但这仅适用于一次合并而不是每次合并。 Gitignore doesn't work obiviously as they don't track this file so all changes in this file will be lost. Gitignore 显然不起作用,因为它们不跟踪此文件,因此此文件中的所有更改都将丢失。

Currently, I have two branch, master and dev.目前,我有两个分支,master 和 dev。 There is a file call .clasp.json.有一个文件调用 .clasp.json。 I want this file be different in these branches on every checkout, and merge should not touch those files.我希望这个文件在每次结帐时在这些分支中都不同,并且合并不应触及这些文件。

I'm thinking if I can write a script that everytime when checkout to a branch, generate the file based on the branch name, I don't know if there is a way of doing it?我在想是否可以写一个脚本,每次结帐到分支时,根据分支名称生成文件,不知道有没有办法做到这一点? I found I can use content filter driver, but there isn't a straight forward document out there, any recommandations please?我发现我可以使用内容过滤器驱动程序,但没有直接的文档,请问有什么建议吗?

What I have tried: This method works in one merge, but the file will still get merged in the next merge.我尝试过的:此方法在一次合并中有效,但文件仍将在下一次合并中合并。 https://stackoverflow.com/a/4516022 https://stackoverflow.com/a/4516022

Whats the Proper usage of .gitattributes with merge=ours This method will only work if there is a merge conflict, which in my case, I won't edit the file after the first edit, I just want it stay different in each branch. .gitattributes 与 merge=ours 的正确用法是什么 此方法仅在存在合并冲突时才有效,在我的情况下,我不会在第一次编辑后编辑文件,我只是希望它在每个分支中保持不同。

The reason you can't do this in Git is that Git isn't about branches.你不能在 Git 中这样做的原因是 Git 与分支无关。 1 1

OK, can't is too strong: as you've shown in your question, you can do it manually.好的,不能太强:正如您在问题中所示,您可以手动完成。 You're correct, though, that using a merge driver in .gitattributes won't work.不过,您是对的,在.gitattributes中使用合并驱动程序是.gitattributes The reason is that when you do run git merge , Git:其原因是,当运行git merge ,Git的方法:

  • computes the merge base;计算合并基数;
  • compares the config file in the base against the one each branch-tip;将 base 中的配置文件与每个 branch-tip 的配置文件进行比较; and
  • if the file is different in only one branch-tip commit, uses that branch-tip-commit version of the file.如果文件仅在一次分支提示提交中不同,则使用该文件的分支提示提交版本。

If you could pick the merge base version of the file manually, you could avoid situations in which two out of the three input files match, but you can't do that.如果您可以手动选择文件的合并基础版本,则可以避免三个输入文件中的两个匹配的情况,但您不能这样做。

So, what can you do?所以,你能做什么呢? There are several classes of options:有几类选项:

  • post-checkout scripts;结帐后脚本;
  • filter drivers;过滤驱动程序;
  • something outside Git itself. Git 本身之外的东西。

The filter driver idea is attractive, but it has a terrible flaw: it runs before Git tells you which branch name was supplied to the git checkout or git switch command.过滤驱动程序的想法很有吸引力,但它有一个可怕的缺陷:它Git 告诉您提供给git checkoutgit switch命令的分支名称之前运行。

The post-checkout script method can work.结帐后脚本方法可以工作。 However, it really leads to the third method: don't do it in Git at all.然而,它确实引出了第三种方法:根本不要在 Git 中进行。 The reason is that you don't want to modify a tracked file (one that is in Git's index / staging-area), which produces all kinds of operational headaches later.原因是你不想修改一个被跟踪的文件(一个在 Git 的索引/暂存区中),这会在以后产生各种操作上的麻烦。

The third method is the one that really works.第三种方法是真正有效的方法。 Use a file that is untracked and ignored, or is entirely outside the Git repository, or a startup directive, to hold the configuration.使用未跟踪和忽略的文件或完全在 Git 存储库之外的文件或启动指令来保存配置。 Allow this file or startup directive to include other files that are in Git, if you like, and/or build this file from files that are in Git.允许此文件或启动指令包括Git的,如果你喜欢的其他文件,和/或处于Git的文件建立此文件。 Have your software read defaults from files that are maintained in Git, if that's useful.如果有用的话,让您的软件从 Git 中维护的文件中读取默认值 But keep the actual configuration elsewhere.但将实际配置保留在别处。

Now that the configuration is outside the Git repository, you can have Git manage the files that are in the repository, without having Git damage the configuration.现在的配置是Git仓库外面,你可以让Git来管理对资源库的文件,而无需Git的损坏配置。


1 More precisely, Git is about commits. 1更准确地说,Git关于提交的。 Commits hold files, but Git isn't about the files;提交持有文件,但 Git 与文件无关; branch names hold commit hash IDs, but Git isn't about the branch names either.分支名称包含提交哈希 ID,但 Git 也与分支名称无关。 The Git operations we care about here—checkout and merge, that is—work on a commit basis, and the "true name" of a commit is its hash ID.我们在这里关心的 Git 操作——签出和合并,即——在提交的基础上工作,提交的“真实名称”是它的哈希 ID。 Many commits are on many branches all at once, and some commits are sometimes on no branch at all.许多提交同时在许多分支上,有些提交有时根本不在任何分支上。 With commits existing without branch names, a branch name cannot be the basis for the existence of a commit.在没有分支名称的情况下存在提交,分支名称不能成为提交存在的基础。 With some commits being the tip of multiple branches, and the stored files inside a commit being read-only, the files literally cannot depend on the branch name.由于某些提交是多个分支的尖端,并且提交中存储的文件是只读的,因此文件实际上不能依赖于分支名称。 Branch names can be changed, and the names can be moved around.分支名称可以更改,名称可以四处移动。 The commits, once made, are fixed in place forever.提交一旦完成,就会永远固定在原地。

In the end, there's just a fundamental mismatch here.最后,这里只是一个根本的不匹配。 If you think about Git as being about commits —rather than branches or files—with commits holding files, everything all works.如果你认为 Git 是关于提交——而不是分支或文件——与提交保存文件,一切都正常。 If you think about Git as being about branches , some parts just don't fit.如果你认为 Git 是关于分支的,那么有些部分就不适合了。

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

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