代码之家  ›  专栏  ›  技术社区  ›  program247365

如何在我在github.com上提交的项目的基础上重新运行本地git存储库的提交?

  •  10
  • program247365  · 技术社区  · 15 年前

    是的,我知道我应该从一开始就分出这个项目,但这就是我现在所处的情况。:)

    我在本地计算机上有一个包含我的博客的本地Git存储库,它有几个月的提交历史。最初,我只是从存储库中下载文件 http://github.com/mojombo/mojombo.github.com 我继续使用本地Git存储库,第一次提交看起来像Mojombo存储库中的最新文件。

    我现在想分叉这个项目,并让我的本地Git存储库提交在它上面重放,所以看起来我从一开始就分叉了这个项目,然后把它推回到我的分叉版本的Mojombo的存储库中,在我的Github帐户上:

    http://github.com/program247365/mojombo.github.com

    所以也许历史会是这样的:

    mobjombo repository:         1---2---3----23
                                      \
    my blog repository commits:       24---25---
    

    我可以使用哪些git命令来执行此操作?

    我看过 this question . 我需要将Mojombo的存储库作为远程文件添加到我的项目中,然后将其拉入、合并、解决冲突,然后在Github上推送到我的分叉项目中吗?

    3 回复  |  直到 6 年前
        1
  •  14
  •   Jakub Narębski adamtaub    11 年前

    简而言之:

    一种解决方案是使用 移植物 要连接历史记录,请使用 git filter-branch 根据这些移植物重写历史,然后选择 合并 .

    请注意,在原始存储库的新开发之上重放更改(提交)的解决方案 重碱 解决方案)是另一个可行的解决方案。


    较长版本:

    让我们假设您记得,或者您可以通过检查源代码和/或使用git命令找到您下载快照的存储库版本,并开始本地开发。让我们称之为修订开始或。

    假设本地断开连接的历史记录位于原始存储库的克隆中。这意味着本地断开连接的开发与项目的完整历史处于同一个存储库中。假设您的本地分支位于分支“master”中(为了简单起见,只有一个分支)。

    如果您没有使用本地断开连接的工作将项目提取到存储库中,则可以使用以下方法执行此操作:

    $ git remote add origin git://github.com/mojombo/mojombo.github.com.git
    $ git fetch origin
    

    历史记录如下:

    *---*---*---*---*---A---*---*---*---*      <--- origin/master (remote-tracking branch)
    
                                         x---y---*---*---*      <--- master (your local disconnected history)
    

    上图中名为a的提交是作为快照下载并启动本地开发的开始提交。

    有两种可能:您已经将“a”的快照作为初始提交“x”提交,或者您进行的第一次提交是通过本地修改进行的。

    在第一种情况下(您提交了原始启动状态,例如“初始提交”或“导入”),您希望连接的历史记录如下所示:

    *---*---*---*---*---A---*---*---*---*      <--- origin/master (remote-tracking branch)
                                          \
                                            \-y---*---*---*       <--- master (your local disconnected history)
    

    也就是说,你第一次承诺“Y”将“A”作为父母。

    在第二种情况下(您提交了更改),您希望连接的历史记录如下所示:

    *---*---*---*---*---A---*---*---*---*           <--- origin/master (remote-tracking branch)
                                          \
                                            \-x---y---*---*---*      <--- master (your local disconnected history)
    

    也就是说,您希望首先提交“x”将“a”作为父级。

    在这两种情况下,您都希望找到提交“a”的完整sha-1标识符,以及提交“x”和“y”的完整sha-1标识符。

    您可以找到提交“a”的sha-1(假设您还不知道)。 git rev-parse :

    $ git rev-parse A     # or A^{commit}
    437b1b20df4b356c9342dac8d38849f24ef44f27
    

    (可能需要“^提交”后缀以确保找到 犯罪 sha-1,如果您(例如)通过其标记知道“a”,例如“v0.99”,这一点很重要;在您的情况下,这是不必要的,因为相关存储库不使用标记)。

    您可以使用查找提交“x”和“y”的sha-1 git rev-list (假设您的开发是在分支“master”上完成的):

    $ git rev-list --topo-order master | tail -2
    8bc9a0c769ac1df7820f2dbf8f7b7d64835e3c68
    e83c5163316f89bfbde7d9ab23ca2e25604af290
    

    (“ | tail -2 “在生成的列表中查找最后两个提交;如果没有,则不需要使用它)。

    注: 在上述所有示例中,完整的sha-1是 实例 ,不应按原样使用!

    让我们首先将您希望“a”(或“start”)作为父级的提交命名为(它将是“x”或“y”,具体取决于您的情况,如上所述)。现在我们使用 嫁接机理 要连接历史记录:

    $ echo "<SHA-1 of FIRST> <SHA-1 of START>" > .git/info/grafts
    

    然后,您应该使用图形历史浏览器(如Gitk、QGit或Gitx)检查是否正确连接(连接)了历史记录,您是否在MacOS X上,甚至是“ git log --graph “或” git show-branch “例如:

    $ gitk master origin/master    # or --all
    

    (这里的Gitk只是一个例子;如果您使用 git show branch “你不总是可以使用” --all “选择权”。

    最后,我们可能希望这些更改是永久性的,所以任何从我们的存储库中获取这些更改的人都将拥有相关的历史记录。我们可以用 git filter-branch :

    $ git filter-branch master
    

    您将在“refs/original/master”中具有原始(断开连接)历史记录。

    现在可以删除移植文件:

    $ rm .git/info/grafts
    

    现在,您可以合并到原始存储库的新开发中:

    $ git merge origin/master
    

    设置每个分支的配置,这样在分支“master”上执行“git pull”就足够了,可以将源(al)存储库中的更改作为练习留给读者……-)


    注: 这个 重新碱溶液 将导致以下历史记录(假设我们有第一个Comit是简单导入的情况):

    *---*---*---*---*---A---*---*---*---*                                      <--- origin/master (remote-tracking branch)
                                                                         \
                                                                           \-y'---*'---*'---*'      <--- master (your local disconnected history)
    

    (何处) y' 意味着承诺 y 已修改:它应该是同一个变更集,但与提交不同)。

        2
  •  5
  •   program247365    15 年前

    当我尝试 git pull 它给了我以下错误:

    $ git pull grid master:master
    ! [rejected]        master     -> master  (non fast forward)
    

    在我的特定案例中,似乎 git rebase 就像这里的步骤所显示的那样,是我要走的路吗?

    #Clone my forked project from github
    git clone git@github.com:program247365/mojombo.github.com.git 
    
    #Add my repo as a remote repo, with the alias 'grid'
    git remote add grid "path/to/remote/gitrep/with/all/history/unrelated/to/mojombo/" 
    
    #Rebase my commits on top of mojombo's
    git rebase master grid/master
    
    #Switch to the local master branch 
    git checkout master
    
    #Call up my mergetool via git, to start rectifying the conflicts that emerge between my repo, and mojombo's
    git mergetool
    
    #Push my rebased/combined repo back to Github.com
    git push github
    
        3
  •  4
  •   mipadi    15 年前

    这里有一个关于你能做什么的想法。这与你在问题底部总结的想法有点相反。

    1. 福克莫朱博在吉特胡布的回购。
    2. 复制您的分叉副本。
    3. 合并现有(原始)存储库中的更改。
    4. 删除您的原始存储库(如果需要,但您不再真正需要它)。

    所以基本上,在Github上分叉之后,您可以使用以下命令序列:

    $ git clone git://github.com/$YOUR_USERNAME/$YOUR_PROJECT.git  # Clone your GitHub fork (#2 from above)
    $ git pull /path/to/your/original/repo master:master           # Clone your original repo's master branch into your new repo (cloned from GitHub)
    $ rm -rf /path/to/your/original/repo                           # Might as well delete the original -- you don't need it anymore, since all your history is in your new repo
    

    总之,此方法将合并您在旧repo中所做的所有更改(从而保留您的开发历史),同时还将引入Mojombo的历史, 允许您跟上莫乔博的变化/如果适用,轻松地将变化贡献回他的回购协议。