如何将提交从一个Git仓库复制到另一个?

Jas*_*nes 63 linux git github

上周我创建了一个Github仓库并忘了选择回购许可证.现在已经有3个大型提交.

我已经问过3个贡献者是否可以,如果我删除了repo,然后再次使用相同的名称创建它,这次在创建repo时选择许可,那么它们就好了.

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

小智 94

有没有办法让我的提交进入新的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
Run Code Online (Sandbox Code Playgroud)

其余的答案是,如果您仍想将LICENSE添加到之前的回购中.

是.您可以通过rebase将LICENSE提交作为第一个提交.

重新引用是重新排列提交顺序的方法,同时保持所有提交作者和提交日期不变.

在处理共享仓库时,除非您的整个团队都是流利的,否则通常会气馁.对于那些没有的人,他们可以只是克隆存储库的新副本.

以下是您将LICENSE提交作为第一次提交的方式.

1.更新并修改本地副本

检查项目并将LICENSE文件放在当前3个提交堆栈的提交ON TOP中.

#create LICENSE file, edit, add content, save
git add LICENSE
git commit -m 'Initial commit'
Run Code Online (Sandbox Code Playgroud)

然后在主分支上执行交互式rebase以重新提交提交.

git rebase -i --root
Run Code Online (Sandbox Code Playgroud)

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

退出编辑器后,git将按您刚刚指定的顺序编写提交.

您现在已更新存储库的本地副本.做:

git log
Run Code Online (Sandbox Code Playgroud)

核实.

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

现在您的副本已更新,您必须强制将其推送到github.

git push -f origin master
Run Code Online (Sandbox Code Playgroud)

这将告诉github将主分支移动到其新位置.你应该只在这样的罕见场合强行推送,每个使用它的人都知道有待更改,否则会让你的合作者感到困惑.

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
Run Code Online (Sandbox Code Playgroud)

而已.现在每个人都应该同步.


Mir*_*Boy 13

我使用了以下方法:

  • 将源存储库克隆到 /c/SrcRepo 等文件夹

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

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

    git pull /c/SrcRepo srcBranch --允许不相关的历史记录

无需创建额外的远程引用

  • 我不小心在原始存储库上提交了更改,而不是在本地提交分叉存储库,您的方法帮助我从原始存储库复制到分叉存储库。 (3认同)

Erf*_*ary 8

你可以试试这个,简单又直接。这会将所有提交推送到您对其他存储库使用的哈希之前(并包括):<last-commit-hash-from-old-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
Run Code Online (Sandbox Code Playgroud)

如果有人需要将所有提交从一个存储库推送到另一个存储库作为单个提交(就像我需要的那样),您可以简单地将--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
Run Code Online (Sandbox Code Playgroud)


WiR*_*R3D 7

基于 @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
Run Code Online (Sandbox Code Playgroud)


Rus*_*ain 6

我有一个类似的问题,在我意识到自己的错误之前,我忘了将一个存储库分叉到我的github并添加了多个提交。

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

首先将遥控器移至原始仓库

git remote remove origin

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

git remote add origin <my repo URL>

然后,我推送给Origin Master,所有提交都显示在github上。

  • 添加到此,当我推送时,我必须执行`git push --set-upstream origin master`,但 Git 让你意识到这一点。 (4认同)

Blu*_*uds 5

现在目标将具有与源相同的数据(您也可以使用 origin 而不是 origin2)