【问题标题】:Replace all existing files in git repository with a different remote branch except the ones in .gitignore用不同的远程分支替换 git 存储库中的所有现有文件,除了 .gitignore 中的文件
【发布时间】:2017-09-13 18:32:00
【问题描述】:

我有几个存储库,我总是必须将一个 core 存储库合并到其中。 core 存储库在每个存储库中设置为 remote 存储库。

一般来说,我更新存储库的工作流程如下:

git reset --hard origin/master
git pull origin master
git fetch core master

然后我执行git merge --squash core/master 并修复所有冲突,然后将存储库推回remote

这很好,只是有点多余,因为除了每个存储库的 .gitignore 文件中的所有内容之外,这些存储库中的所有内容在技术上都应该与 core 存储库相同。

随着存储库数量的增加,我想知道将core 分支拉入这些存储库的更有效方法是什么,我需要替换除.gitignore 中特别提到的文件之外的所有现有文件它们中的每一个,同时保持 git 历史记录和日志的完整性。

【问题讨论】:

  • 你不能用submodule吗?
  • 你想要git checkout branch -- files...吗?
  • Git 在项目级别工作。除非您使用子模块,否则无法为特定文件“选择”备用遥控器。
  • 我很困惑你在这里完成了什么。您以我不会使用的方式使用某些术语 - 核心是远程 repo,而不是远程 branch,具有远程版本的 master 分支。您还有第二个遥控器origin,它也是一个远程仓库,拥有自己的master 分支副本。您是否只是想通过单个本地存储库同步多个远程存储库?如果它们在开发更改/提交中出现分歧,是否有理由不为每组更改使用不同的分支,而不是让它们都在 master 中开发?
  • 上面有人提到了子模块。我会在您考虑的选项中添加子树 - 但是我想首先了解代码位于单独存储库中的原因。只是为了让我们了解核心 repo 与您使用的其他几个 repo 之间的关系。

标签: git git-workflow


【解决方案1】:

您可以结合使用 git 和 bash。我编写了一个示例脚本来展示它是如何完成的。您可以随时修改它并使其变得更好。我也提供了一些解释。该文件名为adder.sh

#!/bin/bash
# $1 -> Files from the branch you want (core)
# $2 -> Branch you want to merge into (master)

git checkout $2
git diff --name-status $1..$2 | grep '^\(D\|M\)\s*' | cut -f2 > ~/.dummy
git checkout $1 -- $(cat ~/.dummy)
git add .

要调用它,只需使用$ sh adder.sh core master。在此之后,来自core 分支的所有新添加和修改的文件都将添加到master 存储库中。使用 git status,您可以查看新内容,然后相应地提交和推送。

$ git commit -m "Skipping Conflicts"
$ git push

对其工作原理的一些解释:

$ git diff --name-status master..core

产生以下输出:

M       public/stylesheets/main.css              # Modified
D       public/templates/createUser.html         # Present in core branch and not master (new file)
A       public/templates/dashboard.html          # Present in master and not in the core branch (don't touch)

所以编写一个简单的正则表达式来只选择修改过的和新的文件,并将其修改为适当的格式,然后将其存储在一个临时文件中。

$ cat ~/.dummy

public/templates/createUser.html
public/stylesheets/main.css

然后我们需要将这些文件添加到我们当前的分支,所以我们使用 git checkout。请参阅this answer 了解如何使用git checkout


还有另一种方法可以做到这一点。官方方式,使用git rerere。来自the man page

在使用相对较长生命周期的主题分支的工作流中,开发人员有时需要一遍又一遍地解决相同的冲突,直到主题分支完成(合并到“发布”分支,或者发送出去并接受上游)。

此命令通过在初始手动合并时记录冲突的自动合并结果和相应的手动解决结果并将先前记录的手动解决方案应用于其相应的自动合并结果来协助开发人员。

注意:您需要设置配置变量 rerere.enabled 才能启用此命令。

This article 对命令及其用例进行了很好的概述。

【讨论】:

  • 除非我做错了,否则这不会维护原始存储库的 git 历史记录。它用核心存储库覆盖它。
  • @KamranKhan,是的,没错。如果你想维护提交历史,你应该冒险第二个选项
  • @KamranKhan,我今天正在查看 git merge 文档,我在 SO 上找到了this answer,看看它是否对你有帮助。
猜你喜欢
  • 2015-05-15
  • 2018-07-08
  • 2019-05-27
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 2012-08-10
  • 2013-02-21
  • 1970-01-01
相关资源
最近更新 更多