Как скопировать коммиты из одного репозитория Git в другой?

102

На прошлой неделе я создал репо на Github и забыл выбрать лицензию для репо. Сейчас уже 3 больших коммита.

Я спросил трех участников, все ли в порядке, удаляю ли я репо, а затем создаю его снова с тем же именем и на этот раз выбирая лицензию при создании репо, и они в порядке.

Вопрос

Есть ли способ получить коммиты в новом репо (на этот раз первая фиксация - это файл LICENSE) и при этом сохранить метаинформацию о фиксации?

Жасмин Логннес
источник
1
Вы по-прежнему можете добавить лицензию в исходное репо. См. Help.github.com/articles/open-source-licensing/… для получения дополнительной информации.
edwinksl

Ответы:

172

Есть ли способ получить коммиты в новом репо (на этот раз первая фиксация - это файл 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

Остальная часть этого ответа - если вы все еще хотите добавить ЛИЦЕНЗИЮ в свое предыдущее репо.

Да. Вы можете разместить свою ЛИЦЕНЗИОННУЮ фиксацию как первую фиксацию путем перебазирования.

Ребазинг - это gits способ изменить порядок фиксации, сохраняя при этом всех авторов фиксации и даты фиксации.

При работе с общим репозиторием это обычно не рекомендуется, если вся ваша команда не владеет git-fluent. Для тех, кто этого не делает, они могут просто клонировать новую копию репозитория.

Вот как вы получаете свою ЛИЦЕНЗИОННУЮ фиксацию как первую фиксацию.

1. Обновите и переустановите локальную копию

Проверьте свой проект и поместите файл LICENSE в фиксацию НА ВЕРХ вашего текущего стека из трех фиксаций.

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

Затем выполните интерактивную перебазировку в главной ветке, чтобы ПОВТОРИТЬ коммиты.

git rebase -i --root

Откроется редактор. Переместите нижнюю строку (ваша «Начальная фиксация», самая последняя фиксация) в верхнюю часть файла. Затем сохраните и выйдите из редактора.

Как только вы выйдете из редактора, 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

Вот и все. Теперь все должны быть синхронизированы.

Moocowmoo
источник
1
Отличный ответ! Благодарность!
Кайрол
Сэкономлено много времени. Благодарность!
an0nh4x0r
9

У меня была аналогичная проблема, когда я забыл разветвить репо на свой github и добавил несколько коммитов, прежде чем осознал свою ошибку.

Я нашел довольно простое решение.

Сначала удалите пульт в исходное репо

git remote remove origin

Во-вторых, добавьте пульт в новую вилку на моем github

git remote add origin <my repo URL>

Затем я нажал на origin master, и все мои коммиты появились на моем github.

Расс Бейн
источник
1
Чтобы добавить к этому, когда я нажал, мне пришлось это сделать git push --set-upstream origin master, но Git дает вам об этом знать.
MRichards
отличное и простое решение!
мекограф
3
  • Пункт назначения Git = UrlD (существующий контент не имеет значения)
  • SourceGit = UrlS

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

Теперь в пункте назначения будут те же данные, что и в источнике (вы также можете использовать origin вместо origin2)

Синие облака
источник
0

Я использовал следующий подход:

  • Клонируйте исходное репо в папку типа / c / SrcRepo

  • Клонируйте целевое репо в папку, например / c / DstRepo, и переключитесь на целевую ветку

  • В корневой папке целевого репо выполните команду:

    git pull / c / SrcRepo srcBranch --allow-несвязанные-истории

Нет необходимости создавать дополнительную удаленную ссылку

ЗеркалоМальчик
источник
0

На основе ответа @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
WiR3D
источник