Как разрешить ветки, когда git diff .. ничего не возвращает, а git diff ... возвращает изменения? - PullRequest
0 голосов
/ 29 мая 2020

Я думаю, что моя основная и релизная ветки как-то разошлись, и мне интересно, как лучше всего вернуть их в синхронизацию c.

У меня есть ветка master, которая должна быть используется для разработки, но затем я объединю эту ветвь master с веткой release для создания окончательных сборок, которые можно будет развернуть. Он работал нормально, но на неделе go всякий раз, когда я пытаюсь создать запрос на перенос, объединяющий master в release, я получаю список коммитов, которые уже должны были быть в release. Я объединю PR, но это продолжает происходить с каждым новым PR, пытающимся объединиться от master до release.

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

git diff upstream/master..upstream/release не дает мне никаких различий.

git diff upstream/release..upstream/master также не дает мне никаких различий.

Однако git diff upstream/master...upstream/release дает мне изменения из всех коммитов, начиная с той, которая, вероятно, расходилась с моими двумя ветвями.

Я думаю, что может происходить то, что мои две ветки идентичны в исходном коде а у них разные коммиты? Я все еще беру занятия по git и о том, как использовать его более эффективно, поэтому любая помощь будет принята с благодарностью!

Ответы [ 3 ]

1 голос
/ 29 мая 2020

Готов поспорить, что если вы запустите git diff upstream/release...upstream/master, вы получите тот же результат, что и третья команда, которую вы там разместили ... и да, ветки разошлись, но у них одинаковое содержимое, поэтому у вас нет различий с 2 точки, но на выходе вы получите 3 точки.

Это все еще не отвечает на ваш вопрос. Это действительно зависит от того, что вы называете «привести их в синхронизацию c».

  • Если вы имеете в виду have the same content: они уже делают
  • Если вы имеете в виду get the branch histories together, вы может попытаться объединить их.
  • Если вы имеете в виду get one branch to have the exact same history as the other, это подразумевает сброс --hard (следовательно, перезапись истории) и некоторое принудительное нажатие.
0 голосов
/ 29 мая 2020

Я думаю, что может происходить то, что мои две ветки идентичны в исходном коде, но имеют разные коммиты?

Да, это правильный диагноз, хотя вы можете подтвердить это с:

git log --left-right --boundary --decorate --oneline --graph
    upstream/master...upstream/release

(все как одно, разбитое на несколько для целей публикации).

Помните, Git примерно фиксирует . Имена ветвей, например master и release, и имена удаленного отслеживания, например upstream/master и upstream/release, идентифицируют конкретную фиксацию. Мы говорим, что эти имена указывают на эти коммиты.

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

Когда у вас есть простая линейная последовательность таких коммитов, каждая из которых имеет свой собственный ha sh ID, заканчивающийся некоторым финальным ha sh ID, который мы можем назвать H, мы можем нарисовать это следующим образом:

... <-F <-G <-H   <-- master

имя master содержит правильный ha sh ID: он позволяет вам (или Git, по крайней мере) легко найти правильный ha sh H для последний коммит в цепочке. Другими словами, master указывает на H. Сам коммит H содержит моментальный снимок - все ваши файлы, замороженные во времени, - а также необработанный sh идентификатор предыдущего («родительского») коммита G, поэтому H указывает на G. Команда ha sh позволяет Git находить G. Коммит G содержит снимок и другой родительский-ha sh, F, который позволяет Git находить F и т. Д.

В этом случае у вас есть такая ситуация :

          I--J   <-- upstream/master
         /
...--G--H
         \
          K--L   <-- upstream/release

По какой-то причине 1 снимки в J и L совпадают, поэтому сравнение upstream/master (фиксация J) с upstream/release (фиксация L) не показывает разницы, независимо от того, в каком направлении вы используете для сравнения.

Здесь полезно знать, что:

git diff A..B

просто означает:

git diff A B

То есть, Git находит два рассматриваемых идентификатора ha sh, извлекает два замороженных снимка и сравнивает (различает) их. Вы видите информацию о том, что необходимо для изменения снимка, который находится в A, на снимок в B,

Но:

git diff A...B

не означает сравнить От A до B , а скорее найдите базу слияния между A и B и сравните этот снимок базы слияния с B . В этом случае, учитывая сделанный мной рисунок, который, вероятно, не совсем соответствует фактическому набору коммитов, который у вас есть, базой слияния upstream/master и upstream/release является фиксация H, которая, как вы можете видеть, присутствует в обоих истории: вы найдете фиксацию H, если начнете с J и будете работать в обратном направлении, и вы также найдете фиксацию H, если начнете с L и будете работать в обратном направлении.

Итак, вот это будет отличать снимок в H от снимка в зависимости от того, на какой коммит указывает имя, которое вы указали справа. Поскольку снимки в J и L совпадают, вы увидите одно и то же различие независимо от того, каким способом вы его запустите:

git diff upstream / master ... upstream / release

сравнивает H против L, а:

git diff upstream/release...upstream/master

сравнивает H против J, но они оба дают одинаковую разницу.

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

  • переместить upstream/release или
  • переместить upstream/master или
  • добавить новую фиксацию слияния и переместить оба, как показано:

              I--J
             /    \
    ...--G--H      M   <-- upstream/release, upstream/master
             \    /
              K--L
    

например. Но все это осложняется тем фактом, что эти два имени являются именами удаленного отслеживания . Это не имена веток, .

Эти имена удаленного отслеживания принадлежат вам, поэтому вы можете их перемещать - но ваши Git автоматически перемещает их в соответствии с идентификаторами ha sh, хранящимися в некоторых других Git именах веток репозитория. Другой репозиторий Git - это тот, который ваш Git называет upstream, а он имеет имена веток master и release. Вы бежите:

git fetch upstream

и ваш Git вызывает их Git, находит все новые коммиты, которых у вас нет (которые вам понадобятся), получает этих коммитов, а затем обновляет ваш upstream/* имена удаленного отслеживания для хранения тех же идентификаторов ha sh, что и их имена ветки .

Следовательно, чтобы обновить имена удаленного отслеживания, правильный способ сделать это чтобы убедить их обновить их ветки имена. Затем вы просто запускаете git fetch upstream, чтобы обновить свой, чтобы он соответствовал.


1 Наиболее вероятная причина, чтобы эти коммиты совпадали, как это, без фиксации слияния на месте, для кто-то использовал git merge --squash или, возможно, щелкающую кнопку веб-страницы GitHub с надписью «squa sh and merge».

0 голосов
/ 29 мая 2020

TIL: git diff имеет другую интерпретацию .. и ... по сравнению с git log.

  • git diff a..b (две точки) совпадает с git diff a b
  • git diff a...b (три точки) сравнивает базу слияния a и b с b

См. docs , «Описание» section.

Выполните: git log --oneline --graph upstream/master upstream/release, вы увидите, как выложены коммиты.


Ваша команда diff с двумя точками действительно показывает вам, что две ветки имеют одинаковое содержимое. 1027

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...