【问题标题】:How to copy commits from one Git repo to another?如何将提交从一个 Git 存储库复制到另一个?
【发布时间】:2016-09-25 02:24:42
【问题描述】:

上周我创建了一个 Github 存储库,但忘记为该存储库选择许可证。现在已经有 3 个大提交。

我已询问 3 位贡献者是否可以删除存储库,然后使用相同的名称再次创建它,这次在创建存储库时选择许可证,他们对此表示满意。

问题

有没有办法让我将提交提交到新的 repo 中(这次第一个提交是 LICENSE 文件)并且仍然保留提交元信息?

【问题讨论】:

标签: linux git github


【解决方案1】:

有没有办法让我将提交提交到新的 repo 中(这次第一个提交是 LICENSE 文件)并且仍然保留提交元信息?

是的,通过在您的第一个提交之上添加一个远程并挑选提交。

# add the old repo as a remote repository 
git remote add oldrepo https://github.com/path/to/oldrepo

# get the old repo commits
git remote update

# examine the whole tree
git log --all --oneline --graph --decorate

# copy (cherry-pick) the commits from the old repo into your new local one
git cherry-pick sha-of-commit-one
git cherry-pick sha-of-commit-two
git cherry-pick sha-of-commit-three

# check your local repo is correct
git log

# send your new tree (repo state) to github
git push origin master

# remove the now-unneeded reference to oldrepo
git remote remove oldrepo

这个答案的其余部分是如果您仍想将 LICENSE 添加到以前的存储库中。

是的。您可以通过变基将您的 LICENSE 提交作为第一个提交。

变基是 gits 重新安排提交顺序的方式,同时保持所有提交作者和提交日期不变。

在处理共享存储库时,通常不鼓励这样做,除非您的整个团队都精通 git。对于那些不是,他们可以克隆存储库的新副本。

这是您将 LICENSE 提交作为第一次提交的方式。

1。更新和变基您的本地副本

检查您的项目并将 LICENSE 文件放在当前 3 个提交堆栈的顶部的提交中。

#create LICENSE file, edit, add content, save
git add LICENSE
git commit -m 'Initial commit'

然后在 master 分支上进行交互式 rebase 以 REARRANGE 提交。

git rebase -i --root

它将打开一个编辑器。将底线(您的“初始提交”提交,最近的提交)移动到文件的顶部。然后保存并退出编辑器。

一旦你退出编辑器,git 就会按照你刚刚指定的顺序编写提交。

您现在已经更新了存储库的本地副本。做:

git log

验证。

2。强制将新的 repo 状态推送到 github

现在你的副本已经更新了,你必须强制将它推送到 github。

git push -f origin master

这将告诉 github 将 master 分支移动到其新位置。 你应该只在这种极少数情况下强制推送,因为使用它的每个人都知道待处理的更改,否则它会让你的合作者感到困惑。

3。将协作者同步到github

最后,所有协作者都必须同步到这个存储库。

首先它们必须有干净的存储库,因为如果有未保存的更改,以下命令可能会造成破坏。

# make sure there are no unsaved changes
git status 

# pull the latest version from github
git fetch  

# move their master branch pointer to the one you published to github.
git reset --hard origin/master

就是这样。现在每个人都应该同步。

【讨论】:

    【解决方案2】:

    我有一个类似的问题,我忘记在我的 github 上创建一个 repo,并在我意识到自己的错误之前添加了几个提交。

    我找到了一个非常简单的解决方案。

    先把远程移除到原来的repo

    git remote remove origin

    第二次在我的 github 上为新的 fork 添加一个遥控器

    git remote add origin <my repo URL>

    然后我推送到 origin master,我的所有提交都显示在我的 github 上。

    【讨论】:

    • 只是补充一点,当我推送时,我不得不做git push --set-upstream origin master,但 Git 会让你意识到这一点。
    【解决方案3】:
    • 目标 Git = UrlD(现有内容无关紧要)
    • SourceGit = UrlS

      git clone UrlS
      
      git remote add origin2 UrlD
      
      git push -f origin2 master
      

    现在 Destination 将具有与 Source 相同的数据(您也可以使用 origin 代替 origin2)

    【讨论】:

    • 请记住,这将重写目标分支上的历史记录。这不仅仅是将您当前的代码作为新提交放在旧代码之上。就我而言,这很好,但请确保这是您想要的。
    【解决方案4】:

    基于@Moocowmoo 的回答,但试图进一步简化它

    这样做的不同之处在于尽可能避免冲突,只是假设遥控器是正确的。

    但它不能很好地处理已删除的文件,因此仍然存在手动元素。

    # assuming you are already on the branch you want to be
    git remote add oldrepo https://github.com/path/to/oldrepo
    git fetch oldrepo
    
    # take all or subset of changes from a branch
    git cherry-pick --strategy recursive --strategy-option theirs oldestCommitHash^..latestCommitHash
    
    # or take all changes included in a specific merge commit (easiest)
    git cherry-pick --strategy recursive --strategy-option theirs mergeCommitHash^..mergeCommitHash
    
    # handling deleted files/unhandled conflicts
    # just keep repeating this section
    git mergetool
    # either c/m or d based on if you want to keep or delete the files
    git cherry-pick --continue
    

    【讨论】:

      【解决方案5】:

      我使用了以下方法:

      • 将源代码库克隆到 /c/SrcRepo 之类的文件夹中

      • 将目标 repo 克隆到 /c/DstRepo 等文件夹并切换到目标分支

      • 在目标仓库的根文件夹中运行命令:

        git pull /c/SrcRepo srcBranch --allow-unrelated-histories

      无需创建额外的远程引用

      【讨论】:

      • 我不小心在原始仓库中提交了我的更改,而不是在本地提交分叉仓库,您的方法帮助我从原始仓库复制到分叉仓库。
      【解决方案6】:

      就我而言,我需要找出新旧存储库之间的差异。所以在新的仓库中添加了旧的。

      git remote add old https://gitlab.site.az/old-blog.git
      

      获取所有遥控器

      git fetch --all
      

      查找不同的提交

      git log --graph --oneline --pretty=format:"%h%x09%an%x09%ad%x09%s" --abbrev-commit --date=relative develop..old/develop
      

      获取您选择的提交

      git cherry-pick SHA1 SHA2 SHA4
      

      【讨论】:

        【解决方案7】:

        你可以试试这个,简单直接。这会将您用作 <last-commit-hash-from-old-repo>hash 之前(包括)之前的所有提交推送到另一个 repo:

        git clone https://github.com/path/to/new-repo.git new-repo
        cd new-repo
        git remote add old https://github.com/path/to/old-repo.git
        git remote update
        git merge --allow-unrelated-histories <last-commit-hash-from-old-repo>
        git push origin main
        

        如果有人需要将所有提交从一个仓库推送到另一个作为单个提交(就像我需要的那样),您可以简单地将 --squash 添加到合并命令像这样:

        git clone https://github.com/path/to/new-repo.git new-repo
        cd new-repo
        git remote add old https://github.com/path/to/old-repo.git
        git remote update
        git merge --squash --allow-unrelated-histories <last-commit-hash-from-old-repo>
        git push origin main
        

        【讨论】:

          猜你喜欢
          • 2015-09-14
          • 2015-08-06
          • 2020-10-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-30
          • 2023-04-06
          • 1970-01-01
          相关资源
          最近更新 更多