如何复制提交从一个 Git 回购到另一个?

上周我创建了一个 Github 回购,忘记为回购选择许可证。现在已经有3个大的提交。

我已经问过3个贡献者,如果我删除了回购,然后用相同的名字再创建一次,这次在创建回购时选择许可,他们是否同意。

提问

有没有一种方法,我可以得到提交到新的回购(这一次的第一个提交是 LICENSE 文件) ,并仍然保持提交元信息?

114791 次浏览

有没有一种方法可以让提交进入新的回购(这次第一个提交是许可证文件) ,同时仍然保留提交元信息?

是的,通过在第一次提交之上添加一个远程提交并初步选择提交。

# 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

这个答案的其余部分是如果您仍然想要添加许可证到您以前的回购。

是的。您可以通过重新定基将您的许可证提交作为第一个提交。

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

当做一个共享回购的工作时,除非你的整个团队都很流利,否则通常是不鼓励的。对于那些不是的,他们可以只克隆一个新的存储库副本。

下面介绍如何在第一次提交时获得许可证提交。

1. 更新本地副本并调整其基础

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

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

然后在主分支上对 重新安排进行交互式重基地提交。

git rebase -i --root

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

一旦退出编辑器,git 将按照您刚才指定的顺序编写提交。

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

git log

来验证。

2. 强制将新的回购状态推到 github

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

git push -f origin master

这将告诉 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

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

我有一个类似的问题,我忘记叉回购到我的 github,并添加了几个提交之前,我意识到我的错误。

我找到了一个非常简单的解决办法。

首先把遥控器移到原来的回收站

git remote remove origin

第二,在我的 github 上的新分叉上添加一个遥控器

git remote add origin <my repo URL>

然后,我推到原始主机和我的所有提交显示在我的 github。

  • 目标 Git = UrlD (现有内容无关紧要)
  • SourceGit = UrlS

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

Now the Destination will have the same data as Source(You can also use origin instead of origin2)

我使用了以下方法:

  • 将源回购复制到/c/SrcRepo 这样的文件夹中

  • 将目标 repo 克隆到/c/DstRepo 之类的文件夹中,并切换到目标分支

  • 在目标回购的根文件夹中运行以下命令:

    Git pull/c/SrcRepo srcBranch 允许不相关的历史

不需要创建额外的远程引用

基于@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

在我的案例中,我需要找出新旧回购协议之间的差异。所以在新的回购中加入了旧的。

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

你可以试试这个,简单明了。这将推动所有提交之前(包括)的 大麻作为 <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

如果有人需要将所有提交从一个回购推到另一个 作为一个单一的承诺(就像我需要的那样) ,你可以简单地将 南瓜添加到 merge 命令中,如下所示:

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