Как создать git Remote-Tracking Branch - PullRequest
0 голосов
/ 23 марта 2019

Они сказали , что так просто, как

Вы можете указать Git отслеживать только что созданную удаленную ветку, просто используя флаг -u с "git push".

Но у меня это никогда не получалось.

Как создать ветку удаленного отслеживания git, с помощью которой

Git теперь может информировать вас о «невыпущенных» и «незаполненных» коммитах.

Вот мое:

$ git status 
On branch newfeature/v4-json
nothing to commit, working tree clean

против того, что я ожидаю, цитируя выше статьи :

$ git status
# On branch dev
# Your branch and 'origin/dev' have diverged,
# and have 1 and 2 different commits each, respectively.
#
nothing to commit (working directory clean)

Т.е., информация о "unpressed" и"unpulled" коммиты.
Т.е. я хочу видеть то же самое, что и:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

И все же из моего фактического вывода выше, вы можете видеть, что я не могу увидеть, сколько коммитов я 'мы сделали до сих пор, несмотря на то, что я сделал несколько коммитов .

Вот что я сделал:

$ git push -u origin newfeature/v4-json
Counting objects: 12, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (12/12), 1.87 KiB | 958.00 KiB/s, done.
Total 12 (delta 9), reused 0 (delta 0)
remote: Resolving deltas: 100% (9/9), completed with 9 local objects.
remote: 
remote: Create a pull request for 'newfeature/v4-json' on GitHub by visiting:
remote:      https://github.com/.../pull/new/newfeature/v4-json
remote: 
To github.com:xxx/yyy.git
 * [new branch]      newfeature/v4-json -> newfeature/v4-json
Branch 'newfeature/v4-json' set up to track remote branch 'newfeature/v4-json' from 'origin' by rebasing.

Но у меня нет такой ветки удаленного отслеживания 'newfeature / v4-json' из 'origin', настроенной git:

A) git remote show origin вообще не отображает ветку удаленного отслеживания для моего нового персонажа:

$ git remote show origin
* remote origin
  Fetch URL: git@github.com:go-easygen/easygen.git
  Push  URL: git@github.com:go-easygen/easygen.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branches configured for 'git pull':
    master             rebases onto remote master
    newfeature/v4-json rebases onto remote newfeature/v4-json
  Local refs configured for 'git push':
    master             pushes to master             (up to date)
    newfeature/v4-json pushes to newfeature/v4-json (up to date)

, хотя я хочу видеть следующее, согласно http://www.gitguys.com/topics/adding-and-removing-remote-branches

$ git remote show origin
* remote origin
  Fetch URL: /tmp/.../git/rp0
  Push  URL: /tmp/.../git/rp0
  HEAD branch: master
  Remote branches:
    master     tracked
    newfeature tracked
  Local branches configured for 'git pull':
    master     rebases onto remote master
    newfeature rebases onto remote newfeature
  Local refs configured for 'git push':
    master     pushes to master     (up to date)
    newfeature pushes to newfeature (up to date)

Обратите внимание, в разделе Remote branches:, кроме master tracked, есть также newfeature tracked.Эта newfeature tracked называется ветвью удаленного отслеживания согласно статье выше.

B) нет ни git branch -a:

$ git branch -a
  master
* newfeature/v4-json
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Там есть только одно remotes/origin/master имя удаленного отслеживания, хотя я ожидаю большего.Например (не имеет значения, но просто для того, чтобы показать случай с более удаленными именами отслеживания),

$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental

C) и git branch -vv:

$ git branch -vv
  master             75369c3 [origin/master] - [*] allow ...
* newfeature/v4-json 8c98d9c - [*] update ...

, пока я ожидаю увидеть,

$ git branch -vv
  master             75369c3 [origin/master] - [*] allow ...
* newfeature/v4-json 8c98d9c [origin/newfeature/v4-json] - [*] update ...

Более того,

git pull не обновляет мою локальную ветку с remote либо:

$ git pull
From github.com:xxx/yyy
 * branch            newfeature/v4-json -> FETCH_HEAD
Already up to date.
Current branch newfeature/v4-json is up to date.

$ git pull
From github.com:xxx/yyy
 * branch            newfeature/v4-json -> FETCH_HEAD
Already up to date.
Current branch newfeature/v4-json is up to date.

$ git pull
From github.com:xxx/yyy
 * branch            newfeature/v4-json -> FETCH_HEAD
Already up to date.
Current branch newfeature/v4-json is up to date.

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

$ git pull
Already up to date.
Current branch master is up to date.

Все выше не нормально.Я много раз создавал Remote-Tracking Branch с MS VS, и результаты были именно такими, как я ожидал, а не выше.Однако мне не нравятся трюки с черной магией, поэтому я хочу знать, как я могу сделать то же самое с обычным git.

Итак, как правильно создать git Remote-Tracking Branch?

1 Ответ

2 голосов
/ 24 марта 2019

Изменить для вывода обновленного адреса (git branch -a и git branch -vv): да, что-то отсутствует . Не совсем понятно, что пошло не так, но у меня есть предположение. Эта часть git push -u вывода:

 * [new branch]      newfeature/v4-json -> newfeature/v4-json
Branch 'newfeature/v4-json' set up to track remote branch 'newfeature/v4-json' from 'origin' by rebasing.

показывает, что ваш Git устанавливает origin/newfeature/v4-json (разделенный на две части) в качестве восходящего потока для newfeature/v4-json. Но ваш git branch -a и git branch -vv вывод показывают, что origin/newfeature/v4-json там нет.

Я могу воспроизвести ключевой элемент этого поведения, создав клон single-branch . Использование git clone --depth=<em>number</em> или git clone --single-branch даст такой клон. Побочным эффектом этого является то, что ваш Git никогда не будет создавать имена для удаленного отслеживания ни для одной ветви , кроме той ветви, о которой вы сказали Git, что вас беспокоит. Если это , проблема заключается в том, чтобы преобразовать клон в обычный (многоотраслевой) клон. (Если вы использовали --depth для создания аспекта с одной ветвью, также может быть целесообразно отменить клон.)

Чтобы узнать, установлен ли ваш клон origin как одно ветвь:

$ git config --get-all remote.origin.fetch

В обычном клоне будет напечатано:

+refs/heads/*:refs/remotes/origin/*

В клоне с одной ветвью и выбранной веткой master будет напечатано:

+refs/heads/master:refs/remotes/origin/master

, который говорит вашему Git: создать имя удаленного отслеживания для master, а не первого создать имена удаленного отслеживания для *, т. Е. Для всех ветвей .

Чтобы отменить единственную ветвь клона origin:

$ git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'

(или отредактируйте .git/config напрямую, например, git config --edit, что является моим предпочтительным методом). См. Также Как мне "отменить" клон --single-branch?

Чтобы преобразовать мелкий клон в полный (не мелкий) клон, просто запустите:

$ git fetch --unshallow

Обратите внимание, что эта операция не зависит от одиночного ветвления, несмотря на то, что git clone связывает их по умолчанию (вы можете переопределить это в git clone время с помощью git clone --depth=<em>number</em> --no-single-branch). В версиях Git до 2.15 нет теста командной строки на мелководье; в 2.15 или позже используйте:

git rev-parse --is-shallow-repository

но до этого вам нужно проверить наличие файла .git/shallow:

if [ -f $(git rev-parse --git-dir)/shallow ]; then
    echo true
else
    echo false
fi

имитирует git rev-parse --is-shallow-repository.

Кроме того, существует проблема с выводом, который вы хотите увидеть. Вы говорите, что хотели бы видеть newfeature как ветвь на пульте дистанционного управления, но не может произойти , поскольку имя newfeature/v4-json должно существовать, что исключает возможность существования newfeature.

(Оригинальный ответ ниже строки.)


$ git push -u origin newfeature/v4-json

Это сработало именно так, как вы просили. Все хорошо в остальной части вывода, который вы показали. Так что не ясно, что вы считаете неправильным; нет ничего плохого Я перейду к другому сообщению, которое вы показали:

# Your branch and 'origin/dev' have diverged,
# and have 1 and 2 different commits each, respectively.

ниже.

Что все это значит? (Long)

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

Во-первых, давайте отметим, что Git действительно все о коммитах . Комитеты являются Git's raison d'être ; без коммитов мы бы вообще не использовали Git. Итак, давайте посмотрим, что такое коммит.

EАч коммит содержит файлов, но это не , а набор файлов.Это снимок всех ваших файлов на момент создания снимка, 1 , но он также содержит некоторые метаданные: информацию о сохраненные данные.Наиболее очевидным является то, что вы видите в выводе git log: ваше имя и адрес электронной почты, а также представление компьютера о том, каким был день и время, когда вы сделали коммит, наряду с причиной , которую вы сохранили длясделать коммит, т. е. ваше лог-сообщение.Все это предназначено для вас - или для кого-то другого - для использования в будущем: когда-нибудь, возможно, завтра, возможно, через месяцы или годы, вы можете оглянуться назад на этот сделанный вами коммит и спросить себя: почему, черт возьмия сделал что ? Ответ должен быть в вашем сообщении журнала.

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

Чтобы найти коммит, Git нужно имя.Эти имена не названия веток!Или, точнее, вы можете начать с использования имени ветви, но это не то имя, которое нужно Git .Истинное имя любого коммита - вместо этого идентификатор хеша .Идентификатор хэша каждого коммита кажется случайным, но на самом деле это криптографическая контрольная сумма всего содержимого коммита, исключительно чувствительная к каждому биту данных в , который фиксирует: всезамороженного снимка, а также ваше имя и отметку времени и ваше сообщение журнала.Вот почему * *1162* вы или кто-либо другой не можете изменить коммит: изменение чего-либо изменяет хэш-идентификатор, и в результате вы получаете новый и другой коммит.Никто не знает, каким будет хэш-идентификатор для нового коммита, пока он не будет сделан.В это время он получает уникальный идентификатор.Никто никогда не будет использовать этот идентификатор для любого другого коммита!И никто не может ничего изменить в коммите: Git будет знать, если вы попытаетесь, потому что идентификатор больше не будет совпадать. 2

Есть один или двапоследние ключевые части этой конкретной головоломки.Во-первых, в каждом новом коммите Git хранит хеш-идентификатор - истинное имя - предыдущего коммита как часть этих метаданных.То есть Git не только сохраняет ваше имя, время и т. Д., Но также сохраняет необработанный хэш-идентификатор коммита, который вы использовали до , чтобы сделать этот новый коммит.Git называет этот сохраненный хеш-идентификатор родительским коммита.Это означает, что каждый коммит указывает на свой родительский коммит в обратной цепочке.

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

A <-B

Если вы извлекаете коммит B, сделайте некоторую работу и сделайте новый коммит C, новый коммит автоматически указывает на B:

A <-B <-C

Что означает это , так это то, что Git должен знать только явно-случайный хэш-идентификатор последнего коммит.В этом случае это коммит C.Если его фактический хэш-идентификатор равен cba9876... или как-то еще, Git может использовать его для поиска содержимого из C.Это содержимое включает в себя фактический хэш-идентификатор commit B.Затем Git может использовать это, чтобы найти B, содержимое которого включает в себя фактический хеш-идентификатор commit A.Git может использовать это, чтобы найти A, а A не имеет родителя, так что теперь, наконец, Git может перестать работать в обратном направлении.

Этот профессионалРабота в обратном направлении от tip tip commit типа C, идентифицируемого как имя ветки , имеет решающее значение в Git. Так история существует . История в репозитории Git - это коммитов, связанных этими стрелками, указывающими назад. Вы начинаете с конца и идете, один коммит за раз, через историю, чтобы увидеть, куда вы можете добраться, следуя стрелкам родителей.

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


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

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


Имена ветвей находят хэш-идентификаторы коммитов

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

A <-B <-C

Нам - и Git - нужен какой-то способ для записи хеш-идентификатора последнего коммита в этой цепочке.

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

  • Названия веток, например master.
  • Имена удаленного слежения, например origin/master. (Git называет эти имена веток для удаленного отслеживания или ветви для удаленного слежения , что я считаю плохим именем; я переключился на использование имен для удаленного слежения , который, я думаю, сложнее ошибиться.)
  • Имена тегов, например v1.3.

На самом деле все они реализованы с помощью одних и тех же базовых методов, но мы просто будем рассматривать их как отдельные формы имени. Филиал Имена имеют специальное свойство; все другие имена не имеют этого свойства.

То, что упоминается в одном из этих имен, довольно просто: это просто фактический необработанный хэш-идентификатор объекта Git, обычно коммит. 3 Таким образом, имя ветви, такое как master , указывает на последний коммит в ветви - коммит C на этом рисунке:

A--B--C   <-- master

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

Когда мы добавляем новый коммит к master, Git автоматически обновляет имя master для хранения хеш-идентификатора нового коммита. Поэтому, если мы создадим новый коммит сейчас, новый коммит D укажет на C:

A--B--C   <-- master
       \
        D

но Git немедленно отрегулирует master, чтобы указывать не на C, а на D:

A--B--C--D   <-- master

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


3 Имена ветвей должны содержать хэш-идентификаторы объектов фиксации, в то время как имена тегов более гибкие.Нам не нужно заботиться об этом здесь.Поскольку значения имен удаленного отслеживания копируются из имен ветвей, имена удаленного отслеживания также содержат только хэш-идентификаторы фиксации.


Имена ветвей являются частными для каждого репозитория, но репозитории общаются.

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

A--B--C--D--G--H   <-- master
          \
           E--F   <-- dev

Чтобы сделать Git действительно полезным, мы регулярно используем Git для обмена работой с другими пользователями Git.Для этого мы обмениваем коммитов .Их хеш-идентификаторы универсальны для всех Gits везде, из-за этого трюка с криптографической контрольной суммой.Учитывая снимок и метаданные, каждые Git везде будет вычислять одинаковый хэш-идентификатор .Поэтому, если мой репозиторий имеет коммиты от A до H, как это, - запомните, что эти заглавные буквы обозначают уникальные, большие уродливые хэш-идентификаторы - и я подключаюсь к вашему репозиторию и вам имеет коммит H, ваш репозиторий также должен иметь тот же коммит, что и мой.

Если у вас нет коммит H, у меня есть коммит, который вы наделите«т.Если у вас есть коммит I или J, , у вас есть коммит, которого I нет.В любом случае, наши Gits могут просто обмениваться хэш-идентификаторами, чтобы узнать, кто что имеет.Тот, кто отправляет коммиты, отправит их, кто получит коммиты, получит их, и отправитель даст получателю любые новые необходимые коммиты.

Допустим, вы принимаете от меня новые коммиты.У меня есть новые коммиты I и J, и мой новый коммит J имеет имя , которое запоминает свой хэш-идентификатор.В моем хранилище у меня есть это:

A--B--C--D--G--H   <-- master
          \
           E
            \
             I--J   <-- dev

По какой-то причине я не имею коммит F, который у вас есть на dev.Вместо этого у меня есть I-J коммитов на моем dev, после (общего) коммита E.

Именно здесь имена удаленного отслеживания входят в

Ваш Git берет мои коммитыI и J.Мой коммит I имеет родителя E.Итак, ваш репозиторий теперь имеет следующее:

A--B--C--D--G--H   <-- master
          \
           E--F   <-- dev
            \
             I--J   <-- ???

Какое имя будет ваше Git-репозиторий используется для запоминания моего коммита I?Лучше не использовать dev: если ваш Git делает ваш dev пункт для коммита I, как вы когда-нибудь снова найдете коммит F?Помните, что он имеет явно-случайный хэш-идентификатор.Вы никогда не сможете угадать это.

Итак, ваш Git использует имена для удаленного слежения , чтобы запомнить мои ветви,Ваш Git делает это:

A--B--C--D--G--H   <-- master, origin/master
          \
           E--F   <-- dev
            \
             I--J   <-- origin/dev

(при условии, что мои master очков совершают H).

Имена origin/master и origin/dev в вашем репозиторий (ваше) имена для удаленного отслеживания , помня мои master и мои dev. 4 Более того, предположим, что вы теперь запрашиваете свой Git, прося его сравнить наборкоммитов, доступных с dev по сравнению с origin/dev, в обычном методе обхода назад, который использует Git.

Начиная с dev, коммиты, которые вы будете посещать, будут F, затем E, затем D и так далее до A.Начиная с origin/dev, коммиты, которые вы будете посещать, будут J, затем I, затем E, затем D и т. Д. До A. Какие коммиты уникальны для какой прогулки?Сколько коммитов вы получаете с dev, чего вы не можете достичь с origin/dev и наоборот?

Отсчитайте их, а затем сравните с тем, что сказал вам ваш Git:

# Your branch and 'origin/dev' have diverged,
# and have 1 and 2 different commits each, respectively.

На самом деле в нашей мозаике отсутствует еще одна часть, которую мы просто опишем в последнем разделе, когда будем говорить о git push ниже.


4 Git иногда называет это tracking , а не , помня , но это еще одно место, в котором Git сильно злоупотребляет словом. Я использовал его во фразе remote-tracking , но, по крайней мере, здесь он переносится и использует это слово в качестве прилагательного, модифицирующего remote .


git push отличается от git fetch

Процесс выше, где ваш Git создал имена для удаленного отслеживания из имен веток, найденных в Git в origin, относится только к git fetch. Это происходит, когда ваш Git вызывает Git на origin и приносит их коммитов you .

Вы, конечно, можете сделать так, чтобы ваш Git вызывал их Git в origin и посылал коммитов. Это операция git push, и она очень похожа. Ваш мерзавец говорит своим мерзавцам о коммитах, которые у тебя есть, а они нет. Давайте нарисуем некоторые. Начнем с этого:

A--B--C--D--G--H   <-- master, origin/master
          \
           E--F   <-- dev
            \
             I--J   <-- origin/dev

Теперь мы запустим git checkout master и git checkout -b newfeature/v4-json, или проще:

git checkout -b newfeature/v4-json master

Теперь у нас есть:

A--B--C--D--G--H   <-- master, origin/master, newfeature/v4-json (HEAD)
          \
           E--F   <-- dev
            \
             I--J   <-- origin/dev

Мы добавили специальное имя HEAD к newfeature/v4-json, чтобы запомнить , имя которого обновляется по мере добавления новых коммитов.

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

                 K   <-- newfeature/v4-json (HEAD)
                /
A--B--C--D--G--H   <-- master, origin/master
          \
           E--F   <-- dev
            \
             I--J   <-- origin/dev

Теперь ваш Git вызовет Git в origin, используя:

git push -u origin newfeature/v4-json

Ваш Git набирает свой Git и объявляет, что у вас есть коммиты K и H. 5 У них нет K, но у них есть H, поэтому у них есть ваш Git отправить через фиксацию K со своим снимком и метаданными. Ваш Git может сказать, что, поскольку у них есть H, у них также есть G и D и все до этого, поэтому вам нужно только отправить им K и его содержимое.

Затем, в конце, ваш Git спрашивает их: Пожалуйста, теперь, если все в порядке, установите ваше имя newfeature/v4-json, чтобы оно указывало на фиксацию K. Обратите внимание, что у вас их нет установите xpt/newfeature/v4-json или что-нибудь подобное. У них есть их ветвь! На самом деле у них нет a newfeature/v4-json, поэтому вполне нормально, что они установят один. Так они и делают! Теперь у них есть newfeature/v4-json в их хранилище , указывающее на коммит K.

Ваш Git сейчас создает ваше имя для удаленного слежения origin/newfeature/v4-json, указывая на фиксацию K, для запоминания их newfeature/v4-json, указывая на commit K. 6 Но это просто означает, что у вашего графа есть одно дополнительное имя , например:

                 K   <-- newfeature/v4-json (HEAD), origin/newfeature/v4-json
                /
A--B--C--D--G--H   <-- master, origin/master
          \
           E--F   <-- dev
            \
             I--J   <-- origin/dev

Из-за опции -u ваш Git сразу же запускается:

git branch --set-upstream-to=origin/newfeature/v4-json newfeature/v4-json

Устанавливает upstream для вашей ветви newfeature/v4-json. Каждая из ваших веток может иметь one (1) upstream, и довольно типично использовать ее именно таким образом. См. Зачем мне все время делать `--set-upstream`? , чтобы узнать больше.


5 Ваш Git мог бы рассказать им о F, но только бы сказал git push origin dev здесь. Используя git push origin newfeature/v4-json, с или без -u, вы сказали своему Git: Расскажите им о коммитах K, H, G, D, C, B и / или A по мере необходимости. Ваши другие неразделенные коммиты намеренно остаются частными.

6 Помните, что благодаря магии хеш-идентификаторов, коммит K универсален для каждого Git везде . Каждый Git либо имеет K по хэш-идентификатору, а затем , что commit; или вообще не имеет K, так что это не имеет значения.

(Это не обязательно на 100% гарантировано. Предположим, хеш-код K на самом деле b5101f929789889c2e536d915698f58d5c5c6b7a. Это хеш-идентификатор коммита в Git-репозитории для самого Git. Если вы никогда не подключаетесь , ваш Git-репозиторий в Git-репозитории для Git, это нормально, что у вас и у них разные коммиты с одним и тем же хэш-идентификатором. Но если вы do когда-либо подключите свой Git-репозиторий к Git-репозиторию для Git, Происходят не так уж и большие вещи. Короткая версия заключается в том, что вы просто не получаете коммит Git, а они просто не получают ваш: два репозитория просто не могут быть объединены в данный момент. Это, вероятно, вполне устраивает и вас, и люди, которые поддерживают Git. Но смотрите также Как недавно обнаруженное столкновение SHA-1 влияет на Git? )

...