git branch, fork, fetch, merge, rebase и clone, в чем различия?

Может кто-нибудь помочь мне понять разницу между веткой, вилкой и клоном в Git?

Точно так же, что это значит, когда я делаю git fetch в отличие от git pull?

Кроме того, что делает rebase значит по сравнению с merge?

Как я могу раздавить отдельных людей, совершающих себя вместе?

Как они используются, почему они используются и что они представляют?

Как фигурирует GitHub?

5 ответов

Решение

Клон - это просто копия хранилища. На первый взгляд, его результат эквивалентен svn checkoutгде вы загружаете исходный код из какого-либо другого хранилища. Разница между централизованными VCS, такими как Subversion, и DVCS, такими как Git, заключается в том, что в Git, когда вы клонируете, вы фактически копируете весь исходный репозиторий, включая всю историю и ветви. Теперь у вас есть новый репозиторий на вашем компьютере, и все сделанные вами коммиты попадают в этот репозиторий. Никто не увидит никаких изменений до тех пор, пока вы не отправите эти коммиты в другой репозиторий (или исходный) или пока кто-нибудь не извлечет коммиты из вашего репозитория, если он общедоступен.

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

http://eagain.net/articles/git-for-computer-scientists/

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

РЕДАКТИРОВАТЬ: так как я не знал о современном определении "fork", используемом такими сайтами, как GitHub, пожалуйста, ознакомьтесь с комментариями, а также с ответом Майкла Дарранта ниже моего для получения дополнительной информации.

Гит

Мой ответ включает в себя GitHub, как многие люди спрашивали об этом тоже.

Локальные хранилища

У git (локально) есть каталог (.git), в который вы фиксируете свои файлы, и это ваш "локальный репозиторий". Это отличается от систем, подобных svn, где вы сразу добавляете и фиксируете удаленный репозиторий.

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

git вообще не "блокирует" файлы и, таким образом, исключает функциональность "эксклюзивной блокировки" для редактирования (на ум приходят более старые системы, такие как pvcs), поэтому все файлы всегда можно редактировать, даже когда они находятся в автономном режиме. На самом деле он выполняет потрясающую работу по объединению изменений файла (в одном и том же файле!) Вместе во время извлечения или извлечения / передачи в удаленный репозиторий, такой как github. Единственный раз, когда вам нужно внести изменения вручную (фактически редактирование файла), это если два изменения затрагивают одну и ту же строку (и) кода.


ветви

Ветви позволяют вам сохранить основной код (ветвь 'master'), сделать копию (новую ветвь) и затем работать в этой новой ветке. Если работа занимает некоторое время или мастер получает много обновлений с тех пор, как была создана ветвь, то следует выполнить слияние или перестановку (часто предпочтительнее для лучшей истории и более простого разрешения конфликтов) с основной ветвью. Когда вы закончите, вы объедините изменения, сделанные в ветви, обратно в главный репозиторий. Многие организации используют ветки для каждой части работы, будь то функция, ошибка или работа по дому. Другие организации используют ветки только для серьезных изменений, таких как обновление версий. Форк: с помощью ветки вы контролируете и управляете ветвью, тогда как с помощью вилки кто-то еще контролирует принятие кода обратно.
Вообще говоря, есть два основных подхода к созданию веток. Первый - сохранить большинство изменений в основной ветке, используя ветки только для более крупных и длительных вещей, таких как изменения версий, где вы хотите иметь две ветки, доступные для разных нужд. Во-вторых, вы делаете ветвь для каждого запроса, исправления ошибки или рутинной работы, а затем вручную решаете, когда на самом деле объединить эти ветки с основной веткой master. Хотя это звучит скучно, это общий подход, который я в настоящее время использую и рекомендую, потому что он обеспечивает чистоту главной ветки и мастер, который мы продвигаем в производство, поэтому нам нужен только законченный, протестированный код, через перебазирование и слияние ветвей.

Стандартный способ привести ветку "в", чтобы освоить это сделать merge, Филиалы также могут быть rebase d "очистить" историю. Это не влияет на текущее состояние и сделано, чтобы дать "более чистую" историю. В основном идея заключается в том, что вы разветвились с определенной точки (обычно от мастера). С тех пор как вы разветвились, "мастер" сам продвинулся вперед. Так что было бы чище, если бы все изменения, которые вы сделали в ветке, воспроизводились против самого последнего мастера со всеми его изменениями. Итак, процесс таков: сохранить изменения; получить "новый" мастер, а затем снова применить изменения против этого. Имейте в виду, что rebase, как и слияние, может привести к конфликтам, которые вы должны разрешить вручную (изменить).

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

Отслеживание веток

Это ветви с именем origin / branch_name (в отличие от просто branch_name). Когда вы загружаете и извлекаете код из / в удаленные репозитории, это фактически механизм, посредством которого это происходит. Например, когда вы git push ветвь с именем 'building_groups', ваша ветвь идет сначала к origin / building_groups, а затем переходит в удаленный репозиторий (на самом деле это слишком упрощено, но пока достаточно). Точно так же, если вы делаете git fetch building_groups полученный файл помещается в вашу ветку origin / building_groups. Затем вы можете объединить эту ветку с вашей локальной копией. Наша практика заключается в том, чтобы всегда делать git fetch и ручное слияние, а не просто git pull (который выполняет оба вышеупомянутых действия за один шаг).

Fetch новые филиалы.

Получение новых веток: в начальной точке клона у вас будут все ветви. Однако, если другие разработчики добавляют ветки и отправляют их на удаленный компьютер, необходимо найти способ "узнать" об этих ветвях и их именах, чтобы можно было их локально свернуть. Это делается через git fetch который получит все новые и измененные ветки в локальном хранилище, используя отслеживающие ветки (например, origin /). однажды fetch Эд, можно git branch --remote перечислить ветви отслеживания и git checkout [branch] на самом деле переключиться на любой данный.

сращивание

Слияние - это процесс объединения изменений кода из разных веток или из разных версий одной и той же ветки (например, когда локальная ветка и удаленная не синхронизированы). Если кто-то разработал работу в филиале и работа завершена, готова и протестирована, то ее можно объединить в master ветка. Это сделано git checkout master переключиться на master филиал, то git merge your_branch, Объединение объединит все разные файлы и даже разные изменения в одни и те же файлы. Это означает, что он фактически изменит код внутри файлов, чтобы объединить все изменения. При выполнении checkout из master также рекомендуется сделать git pull origin master чтобы получить самую последнюю версию удаленного мастера, объединенную с вашим локальным мастером. Если удаленный мастер изменился, т.е. moved forward, вы увидите информацию, которая отражает это во время git pull, Если это так (мастер изменился), вам рекомендуется git checkout your_branch а потом rebase это мастер, так что ваши изменения на самом деле "воспроизводятся" поверх "нового" мастера. Затем вы продолжите получать мастер-версию, как показано в следующем параграфе.

Если нет конфликтов, то в master будут добавлены новые изменения. Если есть конфликты, это означает, что в тех же файлах есть изменения в похожих строках кода, которые он не может автоматически объединить. В этом случае git merge new_branch сообщит, что есть конфликт (ы) для разрешения. Вы "решаете" их, редактируя файлы (в них будут оба изменения), выбирая нужные изменения, буквально удаляя строки изменений, которые вам не нужны, и затем сохраняя файл. Изменения отмечены разделителями, такими как ======== а также <<<<<<<<

После того, как вы разрешите любые конфликты, вы снова будете git add а также git commit эти изменения, чтобы продолжить слияние (во время этого процесса вы получите отзыв от git). Когда процесс не работает хорошо, вы обнаружите, что git merge --abort очень удобно для сброса вещей.

Интерактивный перебазирование и сжатие / изменение порядка / удаление коммитов

Если вы выполнили работу небольшими шагами, например, каждый день вы фиксируете код как "незавершенный", вы можете захотеть "раздавить" эти многочисленные небольшие коммиты в несколько больших коммитов. Это может быть особенно полезно, когда вы хотите делать обзоры кода с коллегами. Вы не хотите воспроизводить все "шаги", которые вы предприняли (посредством коммитов), вы просто хотите сказать, что это конечный эффект (diff) всех моих изменений для этой работы в одном коммите. Ключевой фактор, который необходимо оценить при рассмотрении вопроса о том, следует ли делать это, заключается в том, многократные коммиты направлены против одного и того же файла или файлов более одного раза (в этом случае лучше использовать коммит-фиксации). Это делается с помощью интерактивного инструмента перебазирования. Этот инструмент позволяет сдавливать коммиты, удалять коммиты, перефразировать сообщения и т. Д. Например, git rebase -i HEAD~10 Обратите внимание, что это ~ НЕ - поднимает следующее:
интерактивный перебазинг в Git Будьте осторожны и используйте этот инструмент осторожно. Выполняйте по одному сквошу / удаляйте / переупорядочивайте за раз, выходите и сохраняйте этот коммит, затем снова вводите инструмент. Если коммиты не являются смежными, вы можете изменить их порядок (и затем при необходимости раздавить). Здесь вы также можете удалить коммиты, но вам действительно нужно быть уверенным в том, что вы делаете, когда делаете это!

вилки

Существует два основных подхода к сотрудничеству в git-репозиториях. Первый, подробно описанный выше, напрямую через ветки, которые люди тянут и толкают из / в Эти соавторы имеют свои ssh-ключи, зарегистрированные в удаленном хранилище. Это позволит им напрямую перейти в этот репозиторий. Недостатком является то, что вы должны вести список пользователей. Другой подход - разветвление - позволяет любому "разветвлять" репозиторий, в основном делая локальную копию в своей учетной записи git-репозитория. Затем они могут вносить изменения и по окончании отправлять "запрос на извлечение" (на самом деле это скорее "подталкивание" от них и "вытягивание" запроса для фактического сопровождающего хранилища), чтобы получить принятый код.
Этот второй метод, использующий вилки, не требует, чтобы кто-то поддерживал список пользователей для хранилища.


Github

github (удаленный репозиторий) - это удаленный источник, в который вы обычно отправляете и извлекаете эти зафиксированные изменения, если у вас есть (или добавлены) такой репозиторий, поэтому локальный и удаленный фактически различны. Еще один способ представить себе удаленный репозиторий - это структура каталогов.git, которая находится на удаленном сервере.

Когда вы 'форк' - в графическом интерфейсе веб-браузера GitHub вы можете нажать на - вы создаете копию ("клон") кода в своей учетной записи на github. Когда вы делаете это в первый раз, это может быть немного незаметно, поэтому следите за тем, чтобы в чьем репозитории была указана база кода - либо первоначальный владелец, либо "разветвленный", и вы, например,
Получив локальную копию, вы можете вносить изменения по своему усмотрению (вытягивая и отправляя их на локальный компьютер). Когда вы закончите, вы отправите "запрос на извлечение" первоначальному владельцу / администратору хранилища (звучит странно, но на самом деле вы просто нажимаете на это: - ) и они "вытягивают" это.
Более распространенной для команды, работающей над кодом, является "клонирование" хранилища (щелкните значок "Копировать" на главном экране хранилища). Затем локально наберите git clone [paste]. Это настроит вас локально, и вы также можете нажать и вытащить в (общее) местоположение github.

Клоны

Как указано в разделе о github, клон является копией репозитория. Когда у вас есть удаленный репозиторий, вы запускаете команду git clone для его URL, а затем получаете локальную копию или клон репозитория. У этого клона есть все, файлы, основная ветвь, другие ветки, все существующие коммиты, весь шебанг. Именно с этим клоном вы делаете свои добавления и коммиты, а затем сам удаленный репозиторий - это то, к чему вы подталкиваете эти коммиты. Именно эта локальная / удаленная концепция делает git (и системы, подобные ему, такие как Mercurial) DVCS (распределенной системой контроля версий), в отличие от более традиционных CVS (систем контроля версий кода), таких как SVN, PVCS, CVS и т. Д., Где Вы фиксируете непосредственно в удаленном хранилище.

Визуализация

Визуализация основных понятий можно увидеть на
http://marklodato.github.com/visual-git-guide/index-en.html и
http://ndpsoftware.com/git-cheatsheet.html

Если вы хотите наглядно показать, как работают изменения, вы не можете превзойти визуальный инструмент gitg (gitx для mac) с графическим интерфейсом, который я называю "карта метро" (особенно London Underground), отлично подходит для того, чтобы показать, кто это сделал. что, как все меняется, расходится и сливается и т. д.

Вы также можете использовать его для добавления, фиксации и управления вашими изменениями!

интерфейс gitg / gitx

Хотя gitg / gitx довольно минимальны, в последние 2-3 года (2009-2012) количество инструментов графического интерфейса продолжает расти. Многие пользователи Mac используют вилку gitx от Brotherbard, и для Linux отличным вариантом является smart-git с интуитивно понятным и мощным интерфейсом:

smart-git GUI

Обратите внимание, что даже с инструментом графического интерфейса вы, вероятно, будете выполнять много команд в командной строке.
Для этого у меня есть следующие псевдонимы в моем файле ~/.bash_aliases (который вызывается из моего файла ~/.bashrc для каждой терминальной сессии:

# git
alias gst='git status' # Warning: gst conflicts with gnu-smalltalk (when used).
alias gb='git branch'
alias gco='git checkout'
alias gcob='git checkout -b '
alias ga='git add '
alias gc='git commit'
alias gg='git grep ' #  A great very FAST search option, easier then `find`

Наконец, 6 ключевых спасателей:

1) Вы испортили свою локальную ветку и просто хотите вернуться к тому, что у вас было в прошлый раз, когда вы делали git pull:

git reset --hard origin/master  # You will need to be comfortable doing this!

2) Вы начинаете вносить изменения локально, редактируете полдюжины файлов, а затем, о черт, вы все еще находитесь в основной (или другой) ветке:

git checkout -b new_branch_name  # just create a new branch
git add .                      # add the changes files
git commit -m"your message"    # and commit them

3) Вы испортили один конкретный файл в своей текущей ветке и хотите просто "сбросить" этот файл (потерять изменения) так, как это было в прошлый раз, когда вы извлекали его из удаленного репозитория: git checkout your/directories/filename Это на самом деле сбрасывает файл (как и многие команды git, он не очень хорошо назван для того, что он здесь делает).

4) Вы вносите некоторые изменения локально, вы хотите быть уверенными, что не потеряете их, пока выполняете git reset или rebase: я часто делаю ручную копию всего проекта (cp -r ../my_project ~/) когда я не уверен, могу ли я испортить git или потерять важные изменения.

5) Вы перебазируете, но все портится:

git rebase --abort # To abandon interactive rebase and merge issues

6) Добавьте свою ветку git в приглашение PS1 (см. /questions/30592724/yavlyaetsya-li-kazhdaya-komanda-ddl-sql-obratimoj-kontrol-versij-bazyi-dannyih/30592735#30592735), например,
Филиал selenium_rspec_conversion

Вот изображение Оливера Стила о том, как все это сочетается:

Вилка против Клон - два слова, которые оба означают копию

Пожалуйста, смотрите эту диаграмму. (Первоначально из http://www.dataschool.io/content/images/2014/Mar/github1.png).

.-------------------------.     1. Fork     .-------------------------.
| Your GitHub repo        | <-------------- | Joe's GitHub repo       |
| github.com/you/coolgame |                 | github.com/joe/coolgame |
| ----------------------- | 7. Pull Request | ----------------------- |
| master -> c224ff7       | --------------> | master -> c224ff7 (c)   |
| anidea -> 884faa1 (a)   |                 | anidea -> 884faa1 (b)   |
'-------------------------'                 '-------------------------'
    |                 ^
    | 2. Clone        |
    |                 |
    |                 |
    |                 |
    |                 |
    |                 | 6. Push (anidea => origin/anidea)
    v                 |
.-------------------------.
| Your computer           |  3. Create branch 'anidea'
| $HOME/coolgame          |
| ----------------------- |  4. Update a file
| master -> c224ff7       |
| anidea -> 884faa1       |  5. Commit (to 'anidea')
'-------------------------'

(a) - after you have pushed it
(b) - after Joe has accepted it
(c) - eventually Joe might merge 'anidea' (make 'master -> 884faa1')

вилка

  • Копия в ваше удаленное хранилище (облако), которая связывает его с Джо
  • Копию, которую вы можете затем клонировать в локальный репозиторий, и F*%$- вверх
  • Когда вы закончите, вы можете нажать на свой пульт
  • Затем вы можете спросить Джо, хочет ли он использовать его в своем проекте, нажав pull-request.

клон

  • копия в локальный репозиторий (жесткий диск)

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

Приятно осознавать, что технически клонирование репо и разветвление репо - это одно и то же. Делать:

git clone $some_other_repo

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

Git, как VCS, на самом деле все о клонировании разветвления. Помимо "простого просмотра" с использованием удаленного пользовательского интерфейса, такого как cgit, очень мало общего с git-репо, которое не включает в себя клонирование репо в какой-то момент.

Тем не мение,

  • когда кто-то говорит, что я разветвил репо X, это означает, что он создал клон репо где-то еще с намерением показать его другим, например, для демонстрации некоторых экспериментов или применения другого механизма контроля доступа (например, чтобы позволить людям без Доступ к Github, но с внутренней учетной записью компании для совместной работы).

    Факты: репо, скорее всего, создается с помощью другой команды, кроме git clone то, что он, скорее всего, размещен где-то на сервере, а не на чьем-то ноутбуке, и, скорее всего, имеет немного другой формат (это "голое репо", т. е. без рабочего дерева) - это всего лишь технические детали.

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

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

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

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


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

Другие вопросы по тегам