Не попробовав его...
В мерзавце, если Ваши изменения не были распространены в другой репозиторий, Вы должны быть в состоянии к git rm
затронутый файл (файлы), git rebase --interactive
для переупорядочения фиксации удаления, чтобы быть сразу после фиксации, в которой Вы случайно добавили незаконные файлы, и затем давите те две фиксации вместе.
, Конечно, это не поможет, если кто-то еще вытянул Ваши изменения.
Это сложно сделать. Git сохраняет историю слияния, и если вы выберете «чернильницу» и укажете на фиксацию в bug10101010 в качестве родителя (что означает, что вы выполнили слияние), Git предположит, что все коммиты до этого (назад к точке, где они разделяются) были объединены как хорошо. Это создает проблемы, когда вы хотите выполнить «настоящее» слияние.
С другой стороны, вы можете просто вручную сгенерировать патч из этой (и только этой) конкретной фиксации. Но это также вызовет проблемы, когда вы позже выполните «настоящее» слияние, поскольку оно пытается применить ваш вручную обработанный коммит дважды.
Но опять же, поскольку одна ветка называется «Legacy», я подозреваю, что вы не планируете все равно сделайте это настоящее слияние, и в этом случае вы в значительной степени свободны сделать это в любом случае.
Здесь следует использовать git rebase --onto
и указать диапазон.
(см. git rebase
справочную страницу :
трансплантировать тематическую ветку на основе одной ветки в другую, чтобы представить, что вы разделили ветку темы из последней ветки, используя
rebase - на
.
).
Конечно, это переместит вашу ветку bug10
поверх ветки устаревшей
, что вам не нужно.
Таким образом, можно было бы выполнить эту перебазировку в клонированном репо, а затем объединить эту «расширенную» устаревшую
ветвь (ту, что в репозитории клонов, с ] bug10
модификации поверх него) в локальную и текущую устаревшую
ветку (ту, которую вы хотите изменить, оставив только bug10
).
Сейчас:
(Git1.6.5.1, на старом XP SP2, с сеансом Powershell 1.0 из-за команды Start-Transcript
)
PS D:\> mkdir git
PS D:\> cd git
PS D:\git> mkdir tests
PS D:\git> cd tests
PS D:\git\tests> git init mainRepo
Мне нравится, что мне больше не нужно создавать git сначала каталог репо, затем введите его git init
! Начиная с версии 1.6.5 :
«
git init
» научилсяmkdir
/chdir
в каталог при задании дополнительного аргумента ( т.е. "git init this
").
Это ЗАМЕЧАТЕЛЬНО!
Давайте создадим 3 файла для 3 различных целей.
(В качестве примера я буду хранить изменения файлов отдельно для каждой ветки: здесь нет конфликтов во время слияния или перебазирования.)
PS D:\git\tests> cd mainRepo
PS D:\git\tests\mainRepo> echo mainFile > mainFile.txt
PS D:\git\tests\mainRepo> echo contentToBeFixed > toBeFixedFile.txt
PS D:\git\tests\mainRepo> echo legacyContent > legacy.txt
PS D:\git\tests\mainRepo> git add -A
PS D:\git\tests\mainRepo> git ci -m "first commit"
PS D:\git\tests\mainRepo> echo firstMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "first evol, for making 1.0"
PS D:\git\tests\mainRepo> git tag -m "1.0 legacy content" 1.0
На этом этапе git log --graph --oneline --branches
возвращает:
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
Давайте создадим ветку legacy
PS D:\git\tests\mainRepo> git co -b legacy
PS D:\git\tests\mainRepo> echo aFirstLegacyEvol >> legacy.txt
PS D:\git\tests\mainRepo> git ci -a -m "a first legacy evolution"
Мы вернемся к мастеру, сделаем еще одну фиксацию, которую мы отметим «2.0» (выпуск, который требует исправления ошибок!)
PS D:\git\tests\mainRepo> git co -b master
PS D:\git\tests\mainRepo> git co master
PS D:\git\tests\mainRepo> echo aMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a main evol"
PS D:\git\tests\mainRepo> echo aSecondMainEvolFor2.0 >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a second evol for 2.0"
PS D:\git\tests\mainRepo> git tag -m "main 2.0 before bugfix" 2.0
У нас есть:
* e727105 a second evol for 2.0
* 473d44e a main evol
| * dbcc7aa a first legacy evolution
|/
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
Теперь мы делаем bug10
ветвь с исправлением ошибок:
PS D:\git\tests\mainRepo> git co -b bug10
PS D:\git\tests\mainRepo> echo aFirstBug10Fix >> toBeFixedFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a first bug10 fix"
PS D:\git\tests\mainRepo> echo aSecondBug10Fix >> toBeFixedFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "a second bug10 fix"
Давайте добавим финальную фиксацию в основную ветку
PS D:\git\tests\mainRepo> git co master
PS D:\git\tests\mainRepo> echo anotherMainEvol >> mainFile.txt
PS D:\git\tests\mainRepo> git ci -a -m "another main evol"
Конечное состояние нашего основного репо:
* 55aac85 another main evol
| * 47e6ee1 a second bug10 fix
| * 8183707 a first bug10 fix
|/
* e727105 a second evol for 2.0
* 473d44e a main evol
| * dbcc7aa a first legacy evolution
|/
* b68c1f5 first evol, for making 1.0
* 93f9f7c first commit
На этом stage, дальнейшие манипуляции в mainRepo производить не буду. Я буду клонировать его только для некоторых тестов. Если это не удастся, я всегда могу вернуться к этому репо и клонировать его снова.
Первый клон на самом деле является обязательным,
Теперь мы можем перемотать вперед HEAD
из legacy
на вершину воспроизводимой ветки bug10
.
PS D:\git\tests\rebaseRepo> git co legacy
Switched to branch 'legacy'
PS D:\git\tests\rebaseRepo> git merge bug10
Updating dbcc7aa..cf02bfc
Fast forward
toBeFixedFile.txt | Bin 38 -> 104 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
Контент соответствует тому, что нам нужно:
PS D:\git\tests\rebaseRepo> type legacy.txt
legacyContent
aFirstLegacyEvol
основной
ветви есть только до 1.0
тега (корень для устаревшего
] ветвь) и не далее .
PS D:\git\tests\rebaseRepo> type mainFile.txt
mainFile
firstMainEvol
bug10
исправления находятся здесь:
PS D:\git\tests\rebaseRepo> type toBeFixedFile.txt
contentToBeFixed
aFirstBug10Fix
aSecondBug10Fix
Вот и все.
Идея состоит в том, чтобы вытащить эту «расширенную» устаревшую
ветку в исходное репо, в которой все еще будет bug10
без изменений (т.е. все еще начиная с тега 2.0
, и нигде не воспроизводится, как в случае с rebaseRepo
.
В этом клонированном репо я отслеживаю ветвь origin / legacy
, чтобы объединить на ней ветвь legacy
из другого удаленного источника: rebaseRepo
.
PS D:\git\tests\rebaseRepo> cd ..
PS D:\git\tests> git clone mainRepo finalRepo
PS D:\git\tests> cd finalRepo
PS D:\git\tests\finalRepo> git co -b legacy origin/legacy
В этом исходном репо (я клонировал его только для того, чтобы не вмешиваться в состояние mainRepo, на случай, если мне нужно провести другие эксперименты), я объявлю rebaseRepo
удаленным , и получить его ветки.
PS D:\git\tests\finalRepo> git remote add rebasedRepo D:/git/tests/rebaseRepo
PS D:\git\tests\finalRepo> type D:\git\tests\finalRepo\.git\config
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = D:/git/tests/mainRepo
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "legacy"]
remote = origin
merge = refs/heads/legacy
[remote "rebasedRepo"]
url = D:/git/tests/rebaseRepo
fetch = +refs/heads/*:refs/remotes/rebasedRepo/*
PS D:\git\tests\finalRepo> git fetch rebasedRepo
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From D:/git/tests/rebaseRepo
* [new branch] bug10 -> rebasedRepo/bug10
* [new branch] legacy -> rebasedRepo/legacy
* [new branch] master -> rebasedRepo/master
Теперь мы можем обновить устаревшую
, не касаясь bug10
:
PS D:\git\tests\finalRepo> git merge rebasedRepo/legacy
Updating dbcc7aa..4919b68
Fast forward
toBeFixedFile.txt | Bin 38 -> 104 bytes
1 files changed, 0 insertions(+), 0 deletions(-)
Вы можете повторять процесс столько раз, сколько хотите, при каждом новом ] bug10
коммиты необходимо воспроизвести поверх старой устаревшей
ветки, без включения всех промежуточных коммитов.