`git branch --contains` не показывает ветку, в которой был создан коммит - PullRequest
0 голосов
/ 06 февраля 2020

Я хотел проверить git branch --contains, поэтому я обнаружил фиксацию из ветви, которую я ранее не проверял, older-branch.

В другой, более текущей ветви (позволяет назовите это более новой веткой), я сделал git fetch, чтобы быть в курсе последних событий. Затем я сделал, git branch older-branch --contains COMMITHASH

Но это не вернул старшую ветвь.

Кроме того, когда я сделал git branch --contains COMMITHASH, он показал более новую ветвь, однако не показал более старую ветвь в список.

В замешательстве, я сделал git checkout older-branch, а затем git branch contains older-branch --contains COMMITHASH, и он возвратил old-branch! Затем я сделал git branch --contains COMMITHASH, и он показал более старую ветвь вместе с более новой веткой, на которой я изначально тестировал эти git команды!

Затем я переключился на более новую ветку. На этот раз, когда я сделал git branch older-branch --contains COMMITHASH, он показал старую ветку! Почему это?

1 Ответ

0 голосов
/ 07 февраля 2020

Ваш вопрос по-прежнему полон странных конструкций, таких как:

git branch contains older-branch --contains COMMITHASH

но я думаю Я понимаю, что вы делаете и спрашиваете. (Обратите внимание, что более сфокусированный вопрос может получить более сфокусированный ответ.) Я думаю ответ, который вы хотите получить, - git branch -r --contains. Но в случае, если это не так ...

Основная ошибка, которую вы совершаете, заключается в том, что имена ветвей на самом деле что-то значат для Git. :-) Более конкретно, вы предполагаете, что ваши имена веток обновляются автоматически, когда некоторые другие Git хранилища обновляют их имена ветвей.

Это не так.

Когда вы запускаете git fetch, ваш Git вызывает какой-то другой Git репозиторий. Обычно у вас будет ровно еще один Git репозиторий, который вы назовете origin. Однако вы можете перечислить несколько других Git репозиториев. Вам просто нужно создать уникальное имя для каждого из них.

Теперь предположим, что репозиторий Git находится по адресу origin, который находится по некоторому URL url, имеет три имена филиалов: master, develop и feature. Когда вы запускаете:

$ git clone <url>

, вы получаете Git собственный репозиторий. Ваш репозиторий Git теперь знает о другом репозитории Git - в url - и сохранил этот URL под именем origin:

$ git remote
origin
$ git remote show origin
* remote origin
  Fetch URL: ...
  ... lots more stuff ...

Команда секунда git remote здесь фактически вызвала этот другой Git, чтобы получить от него информацию. Большинство команд, безусловно, в Git не не вызывают другие Git: они только смотрят внутрь вашего Git хранилища.

На данный момент ваш Git репозиторий имеет только одно имя ветви, почти наверняка master. 1 Если вы запустите git branch чтобы перечислить названия веток, вы увидите одну ветку.

Означает ли это, что ветки develop и feature не существуют в вашем хранилище? Ответ на этот вопрос - и нет, и да. Проблема заключается в определении того, что вы подразумеваете под ответвлением . См. Также Что именно мы подразумеваем под "ветвью"?

фиксирует , о которых вы могли бы заботиться, здесь существуют. И действительно, некоторые имена , которые вы, возможно, захотите использовать, тоже существуют! Имена, которые не существуют, являются именами ветвей develop и feature.

Если вы запустите:

git branch --contains <hash-id>

вы определенно не увидите имя develop, потому что у вас нет имени develop.

Я сделал git fetch, чтобы сделать уверен, что я был в курсе последних событий.

Это - или, по крайней мере, a .

... в замешательстве, я сделал git checkout older-branch, а затем [git branch --contains работал на меня]

Это потому, что git checkout иногда создает новую ветку имя .

Ключом здесь снова является неоднозначное значение слова branch . Если вы имеете в виду имя ветви , вы должно иметь имя . Но если вы имеете в виду что-то еще, хорошо ....

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

Когда вы запускаете git fetch origin или git fetch который использует origin, ваш Git вызывает Git на origin. У них есть разговор, и ваш Git получит любые коммиты, которые у вас есть, которые вы не делаете, которые ваш Git хотел бы принять. Затем ваш Git обновит ваши имена для удаленного отслеживания .

В этом случае ваши имена для удаленного отслеживания будут origin/master, origin/develop и origin/feature. Ваш Git создает его для каждого имени ветви , которое ваши Git видят в своих Git.

Эти имена для удаленного отслеживания помнят, для вас / вашего Git, что их Git имели имена ветвей , и какой коммит имеет sh идентификаторы этих имен ветвей. A git fetch обновит их. (Если они удалили некоторые имена веток, вы можете использовать git fetch --prune, чтобы ваш Git удалил соответствующие имена удаленного отслеживания. Без опции сокращения ваш Git будет зависать от дополнительных имен удаленного отслеживания. Это режим чернослива, вероятно, должен быть значением по умолчанию, но по историческим причинам это не так.)

Ваши имена ветвей просто такие: ваше, То, что Фред добавил, удалил и изменил некоторые из своих названий ветвей, не означает, что ваше Git изменит ваших . Если вы подключите ваш Git к пульту с именем fred, ваш Git автоматически обновит ваши fred/* имена, потому что ваши имена Fred-tracking, в то время как ваши, предназначены для запоминания имен Фреда. То же самое относится и к вашим origin отслеживающим именам.

Когда вы сделали git checkout older-branch, ваша команда git checkout просмотрела ваши имена ветвей. Имя older-branch там не было. Вместо того, чтобы сразу сдаться и сказать: у вас нет этой ветви , ваш Git продолжил просматривать все ваши удаленное отслеживание имен.

Если у вас есть одно имя удаленного отслеживания, которое достаточно похоже на имя ветви, которое вы запрашивали, ваш Git сейчас создает ваше собственное имя ветви, соответствующее этому имени удаленного отслеживания. Итак, если у вас есть origin/older-branch, ну, теперь у вас есть есть older-branch. Коммит, обозначенный older-branch, будет таким же коммитом га sh ИД, который origin/older-branch идентифицирует прямо сейчас

Теперь, когда у вас есть имя ветки, вы можете поддерживать это. Вероятно, разумнее удалить его и использовать origin/older-branch напрямую. Команда git branch по умолчанию не выводит список имен для удаленного отслеживания, но с опцией -r это именно то, что она выдаст . Таким образом, git branch -r --contains перечислит те имена удаленного отслеживания, где фиксация имени удаленного отслеживания является потомком фиксации, которую вы * ha sh указываете в командной строке.


1 other Git сообщает, какое имя ветви вы получите по умолчанию, если вы не указали c в своей команде git clone, какую ветку git clone следует создать. Но если кто-то не настроит это иначе, другой Git говорит Я рекомендую master, так что это то, что вы обычно получаете в любом случае.

...