12

我有两个 git 存储库以及它们之间的许多未跟踪的更改:

   ftp -->            C-- (untracked changes) --D
                     /                           \
   git        A--B--C <-- old/master              \
                                                   \
                                                    \
                                  new/master -->     D--E--F 

如何将旧存储库合并到新存储库以具有线性历史记录

A--B--C--D--E--F

编辑:

我如何将 Git 存储库组合成线性历史的启发?

我已经搞定了:

git clone url://new new
cd new/
git remote add old url://old
git fetch old
git reset --hard origin/master
git filter-branch --parent-filter 'sed "s_^\$_-p old/master_"' HEAD
git push origin master

唯一的问题是来自 new/master 的每次提交都加倍(由于我认为父级的更改)所以我现在已经(M 是合并提交)

         D---E---F--         
                    \
A--B--C--D'--E'--F'--M 

如何轻松删除不必要的提交(D - F 可能还有 M)?

4

4 回答 4

6

修复结果git filter-branch

如果您有一个如下所示的存储库:

         D---E---F--
                    \
A--B--C--D'--E'--F'--M <-master

并且您希望结果如下所示:

A--B--C--D'--E'--F' <-master

那么你可以简单地强制master指向F'

git checkout master
git reset --hard <sha1-of-F'>

这将导致提交、、、D和变得无法访问E,从而有效地删除它们(它们将在一段时间后被垃圾收集)。FM

从头开始

假设您有两个如下所示的存储库:

  • 老的: A--B--C <-master
  • 新的: D--E--F <-master

你希望结果是:

  • 结合: A--B--C--D'--E'--F' <- master

然后您可以执行以下步骤:

  1. 初始化combined存储库:

    git init combined
    cd combined
    git remote add old url:/to/old
    git remote add new url:/to/new
    git remote update
    

    此时您的combined存储库如下所示:

    A--B--C <-old/master
    
    D--E--F <-new/master
    

    请注意,这两个分支没有以任何方式连接。

  2. 将您的master分支设置为指向C

    git reset --hard old/master
    

    现在您的存储库如下所示:

          old/master
          |
          v
    A--B--C <-master
    
    D--E--F <-new/master
    
  3. 找到 的 sha1 D

    d=$(git rev-list --reverse new/master | head -n 1)
    
  4. D通过读取提交的内容导入您的工作目录和索引

    git read-tree -u --reset $d
    
  5. D使用与原始提交相同的提交消息、作者、日期等提交内容D

    git commit -C $d
    

    现在您的存储库如下所示:

          old/master
          |
          v
    A--B--C--D' <-master
    
    D--E--F <-new/master
    
  6. 挑选其余的提交:

    git cherry-pick $d..new/master
    

    现在您的存储库如下所示:

          old/master
          |
          v
    A--B--C--D'--E'--F' <-master
    
    D--E--F <-new/master
    
  7. 清理:

    git remote rm old
    git remote rm new
    

    现在您的存储库如下所示:

    A--B--C--D'--E'--F' <-master
    
于 2013-06-15T19:33:13.777 回答
4

只需检查您的分支并运行:

  git reset --hard **SHA-OF-F'**

这将从您的分支中删除MD- 。F

于 2013-06-11T23:59:18.197 回答
1

如果ftp不是一个正确的分支而只是一个复制粘贴工作, 这可以 为你工作

cd git
git rm -r .
cp -r ../ftp/. .
git add
git commit
于 2013-06-06T21:54:01.683 回答
0

好吧,我不确定确切的问题是什么。但我要做的是删除一个包含副本的分支。这些提交是不需要的,并且可能会随着分支被删除而消失。如果它们在同一棵树中加倍,您始终可以git rebase自行承担使用风险。

做类似的事情

git rebase -i HEAD~5

将打开一个编辑器,其中包含您可以做的事情。如果您删除带有提交的行,它将从树中删除它,您可以将提交压缩在一起等。如果您保存一个空文件,它不会做任何事情。

也就是说,请记住,在进行此类变基之后,主分支不会快进,您必须覆盖服务器上的主分支。通过强行推动。换句话说,确保 rebase 正确,并且在推送新分支后,每个人都会在这个分支上同步。如果有人有一个主人并试图推动它失败了,它可能会使事情变得更糟。

Git rebase 就像重放提交历史一样。删除提交更像是跳过更改。如果你跳过一个加倍的提交,那么它不会有任何影响。但是每次提交都会有不同的 shasum,这也意味着分支会偏离原来的 master。

在任何情况下,在做任何事情之前保存 master 的 sha1,然后如果出现问题,只要没有垃圾收集,您总是可以将 master 签出到提交。

删除另一个分支将是最聪明的想法,并且让每个分支都来自该主分支将防止双打。除非你真的不得不这样做,否则应该避免变基。

于 2013-06-15T14:25:10.490 回答