Отменить ребазинг StGit? - PullRequest
       1

Отменить ребазинг StGit?

2 голосов
/ 15 декабря 2011

Я поддерживаю значительную кучу патчей для репозитория Perforce восходящего потока, используя Stacked Git .Я выполнил 'git init' в корневом каталоге извлеченного дерева Perforce и зафиксировал там первичные исходные источники.Затем я локально клонировал этот репозиторий git для создания серии патчей.

Периодически я извлекаю обновления с сервера Perforce, фиксирую их в «нетронутом» зеркале git и затем выполняю:

$ git remote update
$ stg rebase remotes/origin/master

Обычно это просто, но иногда кто-то трогает десятки исходных файлов тривиальным способом (например, используя uncrustify ), что порождает большое количество конфликтов.Когда это происходит, не всегда удобно сортировать мои патчи прямо там и тогда;иногда я хотел бы забыть обо всем этом и просто продолжать работать.

Чтобы справиться с этой ситуацией с помощью стандартного git, я бы создал временную ветвь, в которую можно тянуть / объединять (или перебазировать), и, если мне нравится,конечный результат, удалите мою основную ветку и переименуйте временную ветку в master.Я не совсем понял, как добиться того же, используя stgit.

Я натолкнулся на этот SO вопрос об отмене стандартной git rebase, но можно ли использовать ту же технику с stgit??

Обновление [15.12.2011]: я вынужден констатировать что-то, что, возможно, неочевидно - stg undo делает не (очевидно)делай, что я хочу:

$ stg status
$ stg series
+ add-copyright-notice
+ add-bn-namespace
> fix-tabs
$ git remote update
Fetching origin
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From c:/d/projects/luasand
   57afdac..6b4b209  master     -> origin/master
$ stg rebase remotes/origin/master
Checking for changes in the working directory ... done
Popping all applied patches ... done
Rebasing to "remotes/origin/master" ... done
Pushing patch "add-copyright-notice" ...
  CONFLICT (content): Merge conflict in Variant.h
Error: The merge failed during "push".
       Revert the operation with "stg undo".
stg rebase: 1 conflict(s)
$ stg status
UU Variant.h
M  main.cpp
$ stg undo
Error: Need to resolve conflicts first
stg undo: Command aborted (all changes rolled back)

В показанном выше сценарии я просто хочу сделать вид, что никогда не набирал stg rebase ..., и продолжаю работать, откладывая перебазировку до более удобного времени.Он говорит мне вернуться, используя stg undo, а затем говорит мне, что я должен сначала разрешить конфликты (?!) Как я могу сказать StGit просто забыть все это?

Ответы [ 2 ]

2 голосов
/ 15 декабря 2011

Хорошо, я сам попробую ответить на этот вопрос, хотя мне не очень нравится мой собственный ответ.stg reset --hard, кажется, делает то, что я хочу:

$ stg series
+ add-copyright-notice
+ add-bn-namespace
> fix-tabs
$ git remote update
Fetching origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From c:/d/projects/luasand
   57afdac..d340a1a  master     -> origin/master
$ stg rebase remotes/origin/master
Checking for changes in the working directory ... done
Popping all applied patches ... done
Rebasing to "remotes/origin/master" ... done
Pushing patch "add-copyright-notice" ...
  CONFLICT (content): Merge conflict in Variant.h
Error: The merge failed during "push".
       Revert the operation with "stg undo".
stg rebase: 1 conflict(s)
$ stg log
f2af21a   Thu, 15 Dec 2011 13:23:54 -0500   rebase (CONFLICT)
ebe140c   Thu, 15 Dec 2011 13:23:53 -0500   rebase
a04604e   Thu, 15 Dec 2011 13:22:29 -0500   refresh
a83f169   Thu, 15 Dec 2011 13:22:28 -0500   refresh (create temporary patch)
c2a57d8   Thu, 15 Dec 2011 13:21:50 -0500   new
1770c17   Thu, 15 Dec 2011 13:21:44 -0500   refresh
7613544   Thu, 15 Dec 2011 13:21:44 -0500   refresh (create temporary patch)
bf19372   Thu, 15 Dec 2011 13:20:49 -0500   new
7a67f4c   Thu, 15 Dec 2011 13:20:43 -0500   refresh
ae42ad2   Thu, 15 Dec 2011 13:20:42 -0500   refresh (create temporary patch)
8c91906   Thu, 15 Dec 2011 13:20:12 -0500   new
2b75e5f   Thu, 15 Dec 2011 13:20:11 -0500   start of log
$ stg reset --hard a04604e
Now at patch "fix-tabs"
$ stg series
+ add-copyright-notice
+ add-bn-namespace
> fix-tabs

Кажется, это работает, но я бы предпочел решение, которое не полагается на reset --hard в основной ветке.Я несколько раз выстрелил себе в ногу с помощью этой команды, поэтому теперь я всегда использую трюк «Мастер ситхов», описанный на с.25–26 из Git From The Bottom Up .

Итак ... это ответ на мой первоначальный вопрос, но я надеюсь, что кто-нибудь опубликуетлучше.

0 голосов
/ 16 декабря 2011

Выполнение ребаза «Пробного запуска» серии патчей StGit

Мне не очень понравился мой предыдущий ответ, потому что он использовал reset --hard в основной ветке. Вот рабочий процесс, который использует временную ветвь для предварительного просмотра перебазирования, чтобы увидеть, сколько работы он включает. Если это окажется тривиальным, вы позволите этой ветке заменить вашу основную ветвь, как совет «Мастера ситхов» из стр. 25-26 из Git From The Bottom Up .

Если в ребазе есть масса конфликтов, и вы хотите отложить сортировку до более удобного времени, вы просто переключаетесь обратно на ветку master и продолжаете работать, удаляя временную ветку.

Начальное условие

Предположим, у вас есть рабочее дерево, созданное с помощью stg clone, которое содержит стек патчей, все из которых в настоящее время применяются:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ stg series
+ add-copyright-notice
+ add-bn-namespace
> fix-tabs

Вы обновляете свою удаленную ссылку на репозиторий, из которого вы клонировали, и видите, что произошли некоторые изменения:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ git remote update
Fetching origin
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 4), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From c:/d/projects/luasand
   b22d65f..ab55ba3  master     -> origin/master

Вы думаете: «Я бы хотел быть как можно более актуальным, но я не уверен, что хочу сейчас разобраться с этим ...» Что делать?

Экспорт серии исправлений

Первое, что нужно сделать - выписать серию патчей, чтобы ее можно было импортировать во временную ветку, созданную на следующем шаге:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ stg export --dir=/f/projects/luasand_stg_patches
Checking for changes in the working directory ... done

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ ls /f/projects/luasand_stg_patches
add-bn-namespace  add-copyright-notice  fix-tabs  series

(Существует способ перенести исправления без их экспорта, но я предпочитаю делать это так, потому что они служат резервной копией.)

Создать временную ветку

Затем создайте временную ветку, чтобы просмотреть ребаз. Единственная сложность в этом - выбор базовой ревизии для ветвления. Есть несколько способов сделать это, но я предпочитаю вставлять все патчи и ветки следующим образом:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ stg pop --all
Popped fix-tabs -- add-copyright-notice
No patch applied

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ stg branch --create rbtemp
Checking for changes in the working directory ... done
Recording as a local branch
Branch "rbtemp" created

(Опять же, есть и другие способы сделать это, но я считаю это самым простым.)

Импорт патчей на временную ветку

Следующая команда, которую вы хотите выполнить:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg import -s /f/projects/luasand_stg_patches/series
Checking for changes in the working directory ... done
Importing patch "add-copyright-notice" ... done
Importing patch "add-bn-namespace" ... done
Importing patch "fix-tabs" ... done
Now at patch "fix-tabs"

Конечным результатом является то, что ветка rbtemp выглядит точно так же, как ваша ветка master до того, как вы начали.

Выполнить ребазу

Наконец, вы можете выполнить ребаз во временной ветке. Команда для этого:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg rebase remotes/origin/master
[Output omitted]

Есть несколько способов, которыми это может оказаться, и я сейчас подробно опишу:

Rebase: Путь Дождливого Дня

Поскольку это был мотив для моего первоначального вопроса, я начну со случая, когда в перебазе есть конфликты, с которыми вы не хотите иметь дело в данный момент. Вот как выглядит этот сценарий:

evade@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg rebase remotes/origin/master
Checking for changes in the working directory ... done
Popping all applied patches ... done
Rebasing to "remotes/origin/master" ... done
Pushing patch "add-copyright-notice" ...
  CONFLICT (content): Merge conflict in Variant.h
  CONFLICT (content): Merge conflict in main.cpp
Error: The merge failed during "push".
       Revert the operation with "stg undo".
stg rebase: 2 conflict(s)

Если вы находитесь в центре чего-то, от чего вы не хотите, чтобы вас отстранили, и вам не хотелось бы сейчас исправлять эти конфликты, просто сделайте следующее:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg reset --hard

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg branch master
Checking for changes in the working directory ... done
Switching to branch "master" ... done

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ stg branch --delete --force rbtemp
Deleting branch "rbtemp" ... done

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ stg push --all
Pushing patch "add-copyright-notice" ... done (unmodified)
Pushing patch "add-bn-namespace" ... done (unmodified)
Pushing patch "fix-tabs" ... done (unmodified)
Now at patch "fix-tabs"

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

Rebase: Путь облачного дня

Если у перебазировки есть несколько конфликтов, которые выглядят управляемыми, вы можете решить их сортировать прямо в тот момент в вашей временной ветке. Я представлю, как выглядит этот процесс, включая несколько ошибок, которые я сделал по пути (то есть, забыл сделать git add --update):

evade@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg rebase remotes/origin/master
Checking for changes in the working directory ... done
Popping all applied patches ... done
Rebasing to "remotes/origin/master" ... done
Pushing patch "add-copyright-notice" ...
  CONFLICT (content): Merge conflict in Variant.h
  CONFLICT (content): Merge conflict in main.cpp
Error: The merge failed during "push".
       Revert the operation with "stg undo".
stg rebase: 2 conflict(s)

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ vim Variant.h main.cpp

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ git add --update

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg refresh
Now at patch "add-copyright-notice"

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg series
> add-copyright-notice
- add-bn-namespace
- fix-tabs

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg push --all
Pushing patch "add-bn-namespace" ... done (conflict)
Error: 1 merge conflict(s)
       CONFLICT (content): Merge conflict in main.cpp
Now at patch "add-bn-namespace"

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ vim main.cpp

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg push --all
stg push: Worktree not clean. Use "refresh" or "status --reset"

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg refresh
stg refresh: Cannot refresh -- resolve conflicts first

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ git add --update

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg refresh
Now at patch "add-bn-namespace"

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg push --all
Pushing patch "fix-tabs" ... done (empty)
Now at patch "fix-tabs"

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg series
+ add-copyright-notice
+ add-bn-namespace
> fix-tabs

Команда `` stg push --all` останавливается после каждого неуспешного патча, что дает вам возможность исправить его. По сути, вы продолжаете пытаться протолкнуть все патчи, пока не очистите их. После этого ваш стек патчей снова станет чистым, и он станет последним вышестоящим выпуском. Вы запускаете свои тесты, и они все проходят. Woot!

Единственная проблема: вы проделали всю работу над rbtemp. Так как все прошло хорошо, вам бы очень хотелось, чтобы это было в вашей основной ветке. Не проблема. Просто переименуйте rbtemp в master и удалите старую ветку master:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg branch --rename master old_master
fatal: No such section!
Upgraded branch old_master to format version 2
Renamed branch "master" to "old_master"

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg branch old_master
Checking for changes in the working directory ... done
Switching to branch "old_master" ... done

evadeflow@GILGAMESH /c/d/projects/luasand_stg (old_master)
$ stg branch --rename rbtemp master
fatal: No such section!
Upgraded branch master to format version 2
Renamed branch "rbtemp" to "master"

evadeflow@GILGAMESH /c/d/projects/luasand_stg (old_master)
$ stg branch master
Checking for changes in the working directory ... done
Switching to branch "master" ... done

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$ stg branch --delete --force old_master
Deleting branch "old_master" ... done

evadeflow@GILGAMESH /c/d/projects/luasand_stg (master)
$

И вот вы сидите на своей master ветке, готовые продолжить работу. (Примечание: я не уверен, что означают ошибки fatal: No such section!. Я некоторое время полностью игнорировал эту ошибку без каких-либо побочных эффектов.)

Rebase: Солнечный день Путь

Последний сценарий, который следует рассмотреть, - это когда ваши исправления применяются корректно, без конфликтов, к последней вышестоящей версии.Вот как будет выглядеть вывод rebase в этом случае:

evadeflow@GILGAMESH /c/d/projects/luasand_stg (rbtemp)
$ stg rebase remotes/origin/master
Checking for changes in the working directory ... done
Popping all applied patches ... done
Rebasing to "remotes/origin/master" ... done
Pushing patch "add-copyright-notice" ... done
Pushing patch "add-bn-namespace" ... done (modified)
Pushing patch "fix-tabs" ... done
Now at patch "fix-tabs"

Если вы запустите свои тесты, и они все пройдут, тогда вы просто выполните совет 'Sith Master', обозначенный в конце 'Cloudy'Раздел «Путь дня» выше, чтобы переименовать rbtemp в master и удалить старую ветку master.

Summary

Если вы еще не очень хорошо знаете git и по крайней мере некоторое знакомство с StGit, описанные выше шаги могут показаться ужасно сложными.Они не.Это займет немного времени, чтобы привыкнуть к такой работе.Это не для всех, но если вам нужно поддерживать сложный набор патчей для чужой кодовой базы, это довольно эффективно по сравнению с любыми альтернативами, которые я знаю.(Пожалуйста, прокомментируйте, если у вас есть стратегия, которую вы считаете проще; я всегда стремлюсь улучшить свой рабочий процесс.)

Я не всегда стараюсь создать временную ветку для предварительного просмотра перебазирования.Иногда я просто пробую сначала master и делаю stg reset --hard, если есть конфликты - что не очень часто.Мне нравится сортировка по временной ветке, когда возникают конфликты.Это дает мне определенное спокойствие, зная, что я очень маловероятно, чтобы свернуть свою основную ветвь, в то время как я пытаюсь отменить свою серию патчей.

...