Если у меня есть локальная ветка git под названием feature1 с парой коммитов. Создаю пиар на гитхабе и сливаю его.

Если репозиторий не использует ужасный слияние сквоша на github *, я могу использовать его после обновления ветки master / main:

git branch --merged
* main
feature1

Чтобы легко увидеть, какие из моих функциональных веток уже объединены в обновленную ветку main / master.

Теперь, если репозиторий github выполняет слияние Squashed, как мне программно выяснить, была ли ветка слита в master / main или нет?

1
Gabriel 10 Окт 2020 в 01:52

1 ответ

Лучший ответ

В общем случае это невозможно, но вас это может не волновать по двум причинам:

  • GitHub не предоставляет полный общий случай.
  • Некоторые из этих полных общих случаев в любом случае равносильны придиркам.

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

Однако, насколько мне известно, заранее написанного решения, которое можно было бы просто использовать , не существует. Вам придется написать свою собственную программу - возможно, простой сценарий оболочки. (Однажды я начал с одного, но никогда не возвращался, чтобы его исправить. В некоторых случаях бывает сложно.)

Когда кто-то использует кнопку REBASE AND MERGE или SQUASH AND MERGE на GitHub, он добавляет в свой репозиторий GitHub либо одну фиксацию - SQUASH AND MERGE < / kbd> - или несколько коммитов с помощью REBASE AND MERGE . У этих коммитов есть некоторые отличительные особенности, так что после того, как вы git fetch их коммиты из их репозитория, вы можете сравнить эти коммиты с вашим выполняет фиксацию в вашей ветке feature:

  • Во-первых, и это, возможно, наиболее важно, каждый из этих коммитов может быть сгенерирован механически самим Git, запустив либо git rebase, либо git merge --squash: такая команда будет выполняться до завершения без конфликтов слияния. Это означает, что вы можете сделать то же самое в своем собственном репозитории Git и посмотреть, работает ли он и создает ли тот же исходный снимок.

  • Во-вторых, если они использовали REBASE AND MERGE , будет однозначное соответствие между каждым из их коммитов и коммитами, которые ваш собственный Git скопирует, когда вы запустите ребазирование без взаимодействия. в вашем собственном репозитории. Если они использовали SQUASH AND MERGE , этого не будет, и вы захотите запустить git merge --squash без взаимодействия в своем собственном репозитории, чтобы увидеть, получите ли вы тот же исходный снимок без конфликтов.

Если мы делаем некоторые часто, но не всегда верные, упрощающие предположения, мы можем выполнить проверку, не выполняя на самом деле git rebase или git merge --squash. Это особенно полезно для случая перебазирования, потому что есть несколько разных способов запустить перебазирование, каждый из которых имеет немного разные подводные камни, и мне, по крайней мере, не ясно, какой из этих методов использует GitHub (или они могли сколотить свои собственный неинтерактивный эквивалент обнаружения конфликтов с использованием git cherry-pick).

Это самое большое упрощение. Если у нас есть та же начальная точка, что и у них, тогда каждая скопированная фиксация или отдельная сжатая фиксация будет создавать тот же исходный моментальный снимок, который есть в каждой из наших фиксаций, или в конце нашей ветки feature. То есть предположим, что мы делаем PR, когда у нас есть такое состояние:

...--o--o--*   <-- remote/main
            \
             A--B--C   <-- our-feature

Они используют любой из этих двух раздражающих режимов, которые копируют наши коммиты, так что идентификаторы хешей не совпадают, или раздавливают (тот же эффект). Мы загружаем их новые коммиты в наш собственный репозиторий, и теперь у нас есть:

...--o--o--*--ABC   <-- remote/main
            \
             A--B--C   <-- our-feature

Или же:

...--o--o--*--A'-B'-C'  <-- remote/main
            \
             A--B--C   <-- our-feature

В обоих случаях последний коммит их ветки - наш remote/main коммит, который является либо ABC, либо C' - имеет тот же исходный снимок , что и наш commit C на кончике нашего feature. Так:

git rev-parse remote/main^{tree}

А также:

git rev-parse feature^{tree}

Создаст тот же идентификатор хеша .

Это конкретное упрощение не работает, когда они начинают с фиксации, которая не является нашей вершиной, так что у них есть:

...--o--o--*--X--ABC   <-- main

В их репозитории, например. Теперь их фиксация сквоша ABC не соответствует нашей фиксации C из-за дополнительной фиксации X. Это выполняется , но становится труднее проверить , если они делают следующее:

...--o--o--*--ABC--X   <-- main

Потому что теперь нам нужно найти фиксацию ABC, работая в обратном направлении от кончика нашего remote/main после того, как мы извлечем цепочку ABC-X и добавим ее в наш собственный репозиторий.

Для случая «поломки» нам действительно нужно воспроизвести действие, которое предпринял GitHub, чтобы мы могли проверить, соответствует ли исходный снимок тому, что Git может механически произвести самостоятельно (если вообще что-то). Это требует перечисления всех новых для нас коммитов после операции git fetch, так что это становится беспорядочным.

3
torek 9 Окт 2020 в 23:59