如何维护(大部分)并行分支,只有很少的差异

发布于 2024-08-19 10:04:44 字数 419 浏览 5 评论 0原文

场景:我正在尝试在 git 下获取我的 unix 点文件。我必须(至少)在 cygwin 环境和一些标准 Linux 发行版(ubuntu 和 opensuse)之间工作,并且我有仅特定于 cygwin 的文件/代码行。由于我不想签出无用的文件或必须处理点文件中的大量情况,因此我正在为每个环境创建分支。但我所做的大多数编辑对于所有环境都是通用的,因此几乎每次我进行提交时,我都需要将该更改传播到我的所有分支。

所以基本上我有几个几乎相同的分支,除了一些提交之外,而且大多数提交我确实需要位于所有分支中。

问题:推荐的 git 工作流程是什么(如果有的话)?或者对于我的场景有更好的设置(不使用多个分支?)?

[我尝试过挑选,但这涉及相当多的工作,更不用说这里所有的重复提交以及保持我的分支同步的噩梦。]

Scenario: I'm trying to get my unix dot-files under git. I have to work between (at least) the cygwin environment and some standard linux distros (ubuntu and opensuse), and I have files/lines of code that are only specific to, say, cygwin. Since I don't want to checkout useless files or have to deal with lots of cases inside my dotfiles, I'm creating branches for each of my environments. But most of the edits I do are common to all environments, so almost every time I made a commit I need to propagate that change to all my branches.

So basically I have several branches that are almost identical except for a few commits, and most commits I do need to be in all branches.

The question: what is the recommended git workflow for this, if there is any? Or is there a better setup (without using multiple branches?) for my scenario?

[I tried cherry-picking, but that involves quite a bit of work, and not to mention all the duplicate commits out here and the nightmare it is to keep my branches in sync.]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尝蛊 2024-08-26 10:04:44

对于这种特殊情况,在一个分支中存在大量通用文件,而每个环境只有少数特定的配置文件……我们不会将配置文件存储在 Git 中。完全没有。

我们确实存储所述配置文件的模板,加上所有特定的每个环境值,再加上能够用正确值替换模板文件中的变量的脚本(检测当前平台)

这样,我们不需要只为这些文件创建分支。


管理此类文件(具有特定于平台的内容)的另一种好方法是通过 git 属性过滤器驱动程序(另请参阅Pro Git书)。

过滤器驱动程序由一个clean命令和一个smudge命令组成,其中任何一个命令都可以不指定。
checkout 时,当指定 smudge 命令时,该命令将从其标准输入提供 blob 对象,并使用其标准输出来更新工作树文件。
类似地,clean 命令用于在签入时转换工作树文件的内容。

这样,污迹引用的脚本(由 Git 管理)可以用特定于平台的值替换所有变量,而干净的脚本会将其内容恢复到未更改的配置文件中。

http://git-scm.com/figures/18333fig0702-tn.png

主要思想仍然是:避免仅创建分支对于这种平行进化。

For that particular case, where there is a lot of common files evolving in one branch, and only a few config files specific per environment... we do not store the config file in Git. At all.

We do store template of said config files, plus all the specific per-environment values, plus a script able to replace the variables in the template files by the correct value (detecting the current platform)

That way, we do not need to make a branch only for those files.


Another good way to manage those kind of files (with a platform-specifc content) is through a git attribute filter driver (see also Pro Git book).

A filter driver consists of a clean command and a smudge command, either of which can be left unspecified.
Upon checkout, when the smudge command is specified, the command is fed the blob object from its standard input, and its standard output is used to update the worktree file.
Similarly, the clean command is used to convert the contents of worktree file upon check-in.

That way, a script (managed with Git) referenced by the smudge can replace all the variables by platform-specific values, while the clean script will restore its content to an untouched config file.

http://git-scm.com/figures/18333fig0702-tn.png

The main idea remains: avoid creating branches only for that kind of parallel evolution.

纵性 2024-08-26 10:04:44

一种方法是为每个环境保留一个分支,再加上一个所有环境通用的“主”分支。每当您对 master 分支进行更改并希望将其拉入另一个系统时,请执行以下操作:

git pull
git checkout local
git rebase master

这将根据“master”的当前状态重写“本地”(针对此特定环境)的当前更改。

您需要注意的手动操作是在哪里提交您想要进行的更改。如果它是系统本地的,请将其提交到该系统的“本地”分支,否则将其提交到“master”并将其推送到公共存储库。

当然,变基可能会导致您必须手动解决的冲突。此外,如果您选择将本地分支推送到公共存储库,则必须 (a) 为每个环境选择唯一的名称,以及 (b) 处理变基后的非快进推送。这两个问题都是可以解决的。

One approach is to keep a branch for each environment, plus a "master" branch that is common to all environments. Whenever you make a change to the master branch and want to pull it into another system, do something like:

git pull
git checkout local
git rebase master

This will rewrite the current changes on "local" (that are for this particular environment) against the current state of "master".

The manual thing you'd need to pay attention to is where you commit a change you want to make. If it's local to a system, commit it to that system's "local" branch, else commit it to "master" and push it up to a common repository.

Of course, rebasing may result in conflicts that you have to resolve manually. Also, if you choose to push local branches to the common repository, you'd have to (a) choose unique names for each environment, and (b) deal with the non-fast-forward pushes after rebasing. Both these problems are solvable.

夏の忆 2024-08-26 10:04:44

好问题。尽管你说:

...因为我不想签出无用的文件...

我会将特定于平台或特定于变体的项目放在与主代码相同的分支中,但放在该平台/变体的单独目录中。关键是将特定于平台的内容隔离到尽可能小的区域(即避免主代码中的ifdef)。

例如:

/
+--common
+--linux
+--cygwin
+--windows
+--mac

各种跨平台项目都是以这种方式组织起来的。例如,查看Python支持多平台的源代码结构。

它简化了您在这方面的工作流程,因此您可以更自由地将分支用于其他更有趣的目的。

Good question. Even though you said:

...Since I don't want to checkout useless files...

I would go for putting the platform-specific or variant-specific items in the same branch as the main code, but in a separate directory for that platform/variant. The key is to isolate the platform-specific stuff to as small an area as possible (i.e. avoid the ifdefs in the main code).

E.g.:

/
+--common
+--linux
+--cygwin
+--windows
+--mac

Various cross-platform projects organise themselves in this way. E.g. check out Python's source code structure for supporting multiple platforms.

It simplifies your workflow in this regard, so you are more free to use branches for other more interesting purposes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文