git reset --soft - он возвращается к точке проверки git или к последней точке слияния git? - PullRequest
0 голосов
/ 02 сентября 2018

Я думаю, что я ищу самого старого общего предка двух веток, или что-то в этом роде, этот вопрос, кажется, касается этого: Нахождение точки ветвления с помощью Git?

Но вместо диаграммы в ОП, это больше того, на что я смотрю:

-- I -- I -- I -- I -- I -- I -- I  (integration branch) 
          \         \          /
           \         \        /
             F -- F -- F -- F  (feature branch)

У меня вопрос: если мы извлекаем ветку функций из интеграции и вносим некоторые изменения и некоторые коммиты, а затем мы обновляем или объединяем интеграцию несколько раз по ходу работы. Ака, фиксация коммитов, слияние с интеграцией, коммит коммитов, слияние с интеграцией и т. Д. Если мы затем сделаем git reset --soft <integration>, будет ли это сбрасывать его в коммит при интеграции, когда использовался git checkout, или он просто сбросит это к точке, где произошла последняя git merge с интеграцией?

Цель состоит в том, чтобы я мог превратить свою функцию в один большой коммит. Если git reset --soft возвращается только к последнему слиянию git с интеграцией, то моя функция может иметь сотни коммитов, что не является буэно, и мне понадобится другая техника.

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Вы можете использовать git reset --soft, но есть еще кое-что, что вы должны сделать - или, скорее, не сделать - сначала.

Цель состоит в том, чтобы я мог превратить свою функцию в один большой коммит.

В этом случае убедитесь, что не начинаются с:

-- o -- A -- B -- C -- D -- E -- IM   <-- integration
          \         \          /
           \         \        /
            F1 -- F2 - FM - F4   <-- feature

Обратите внимание, что я заменил отдельные буквы здесь, чтобы я мог говорить о конкретных коммитах. Что касается самого Git, то двумя наиболее интересными коммитами являются F4, который является коммитом tip ветви с именем feature, и IM, который является коммитом tip ветви с именем integration.

Коммит, помеченный FM, не является проблемой, хотя является коммитом слияния. Коммит, помеченный IM , является проблемой. Это потому, что этот коммит доступен из кончика integration. Более подробное описание концепции достижимости см. В Think Like (a) Git . Всякий раз, когда сам коммит IM доступен, начиная с коммита, на который указывает integration, и работая в обратном направлении (влево), все коммиты, которые достигает сам коммит IM, достигают. Фиксация IM приводит к фиксации E (не проблема) и F4 (проблема!).

Если вы исключаете коммит IM, так что у вас есть:

-- o -- A -- B -- C -- D -- E   <-- integration
          \         \
           \         \
            F1 -- F2 - FM - F4   <-- feature

теперь вы можете git checkout feature и запустить git reset --soft integration, в результате чего:

-- o -- A -- B -- C -- D -- E   <-- feature (HEAD), integration
          \         \
           \         \
            F1 -- F2 - FM - F4   [abandoned, but remembered as feature@{1}]

Ваши index и work-tree не изменились по сравнению с тем, когда вы зафиксировали коммит F4, поэтому теперь вы можете запустить git commit, чтобы превратить текущий индекс в новый коммит. Имя feature теперь будет указывать на новый коммит:

                              F   <-- feature (HEAD)
                             /
-- o -- A -- B -- C -- D -- E   <-- integration
          \         \
           \         \
            F1 -- F2 - FM - F4   [feature@{1}]

Снимок для нового коммита F будет совпадать с моментом для коммита F4:

git diff feature@{1} feature

вообще ничего не печатает. Но родительский нового коммита F является существующим коммитом E. (В коммите F также есть новый автор и коммиттер и соответствующие метки времени "сейчас", что также отличает его от F4.)

0 голосов
/ 02 сентября 2018

Каждый раз, когда вы объединяете функцию обратно в integration, вы перемещаете integration HEAD (которая теперь ссылается на новый коммит слияния)

Вам нужно пометить integration до того, как сделает вашу ветку feature и ваши слияния, чтобы вернуться к ней.

Один из возможных маркеров будет origin/integration: это последний раз, когда вы выбираете integration).

Еще один git merge-base --fork-point (основанный на reflog, такой ненадежный) или некоторый дифференциал между git rev-list --first-parent обеих ветвей.

В любом случае ваш git reset --soft должен будет использовать этот маркер, не локальную ветвь интеграции.

...