В чем различия между git branch, fork, fetch, merge, rebase и clone? - PullRequest
487 голосов
/ 25 июля 2010

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

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

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

Как я могу раздавить отдельных коммитов?

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

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

Ответы [ 5 ]

520 голосов
/ 09 февраля 2012

1001 * Гит * Этот ответ включает в себя GitHub, как об этом спрашивали многие. Локальные репозитории Git (локально) имеет каталог (.git), в который вы фиксируете свои файлы, и это ваш «локальный репозиторий». Это отличается от систем, подобных SVN, где вы сразу добавляете и фиксируете удаленный репозиторий. Git хранит каждую версию файла, которая изменяется при сохранении всего файла. В этом отношении он также отличается от SVN, поскольку вы можете перейти к любой отдельной версии, не «воссоздавая» ее с помощью дельта-изменений. Git вообще не «блокирует» файлы и, таким образом, исключает функциональность «эксклюзивной блокировки» для редактирования (вспоминаются более старые системы, такие как pvcs), поэтому все файлы всегда можно редактировать, даже когда они находятся в автономном режиме. На самом деле он выполняет потрясающую работу по объединению изменений файла (в одном и том же файле!) Вместе во время извлечения или извлечения / передачи в удаленный репозиторий, такой как GitHub. Единственный раз, когда вам нужно внести изменения вручную (фактически редактирование файла), это если два изменения затрагивают одну и ту же строку (и) кода. Филиалы Ветви позволяют вам сохранить основной код (ветку 'master'), сделать копию (новую ветку) и затем работать в этой новой ветке. Если работа занимает некоторое время или мастер получает много обновлений с тех пор, как была создана ветвь, то следует выполнить слияние или перестановку (часто предпочтительнее для лучшей истории и более простого разрешения конфликтов) с основной ветвью. Когда вы закончите, вы объедините изменения, сделанные в ветке, с главным репозиторием. Многие организации используют ветки для каждой части работы, будь то функция, ошибка или работа по дому. Другие организации используют ветки только для серьезных изменений, таких как обновление версий. Форк: с помощью ветки вы контролируете и управляете ветвью, тогда как с вилкой кто-то еще контролирует принятие кода обратно. Вообще говоря, есть два основных подхода к созданию веток. Первый - сохранить большинство изменений в основной ветке, используя ветки только для более крупных и длительных вещей, таких как изменения версий, где вы хотите иметь две ветки, доступные для разных нужд. Во-вторых, вы делаете ветку для каждого запроса, исправления ошибки или рутинной работы, а затем вручную решаете, когда на самом деле объединить эти ветки с основной веткой master. Хотя это звучит скучно, это общий подход, который я в настоящее время использую и рекомендую, потому что он сохраняет главную ветвь чище, и это основной продукт, который мы продвигаем в производство, поэтому нам нужен только законченный, проверенный код, через перебазирование и слияние ветвей. Стандартный способ привести ветвь 'в' к мастеру - это сделать merge. Ветви также могут быть «перебазированы», чтобы «очистить» историю. Это не влияет на текущее состояние и делается для того, чтобы «очистить» историю. По сути, идея в том, что вы разветвляетесь с определенной точки (обычно от мастера). С тех пор как вы разветвились, сам «мастер» с тех пор продвинулся от этой точки ветвления Это будет «чище» (легче решать проблемы, а историю будет легче понять), если все изменения, которые вы сделали в ветке, будут воспроизведены против текущего состояния мастера со всеми его последними изменениями. Итак, процесс таков: сохранить изменения; получить «новый» мастер, а затем повторно применить (это часть rebase) снова изменения против этого. Имейте в виду, что rebase, так же как и merge, может привести к конфликтам, которые вам придется разрешать вручную (т.е. редактировать и исправлять). Одно замечание:
Перебазировать, только если ветка локальна, а вы еще не перешли на удаленную!
Это происходит главным образом потому, что перебазирование может изменить историю, которую видят другие люди, включая собственные коммиты. Отслеживание веток Это ветви с именем origin/branch_name (в отличие от branch_name). Когда вы загружаете и извлекаете код из / в удаленные репозитории, это фактически механизм, посредством которого это происходит. Например, когда вы git push ветвь с именем building_groups, ваша ветвь сначала переходит к origin/building_groups, а затем она отправляется в удаленный репозиторий. Точно так же, если вы делаете git fetch building_groups, полученный файл помещается в вашу ветку origin/building_groups. Затем вы можете объединить эту ветку с вашей локальной копией. Наша практика заключается в том, чтобы всегда выполнять git fetch и ручное слияние, а не просто git pull (который выполняет оба действия за один шаг). Загрузка новых веток. Получение новых веток: в начальной точке клона у вас будут все ветви. Однако, если другие разработчики добавляют ветки и отправляют их на удаленный компьютер, необходимо найти способ «узнать» об этих ветвях и их названиях, чтобы можно было их локально свернуть. Это делается с помощью git fetch, который получает все новые и измененные ветки в локальный репозиторий, используя ветви отслеживания (например, origin/). Как только fetch ed, можно 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 ( note: это ~, а не -) вызывает следующее: interactive rebasing in Git Будьте осторожны и используйте этот инструмент осторожно. Выполняйте по одному сквошу / удаляйте / переупорядочивайте за раз, выходите и сохраняйте этот коммит, затем снова вводите инструмент. Если коммиты не являются смежными, вы можете изменить их порядок (и затем при необходимости раздавить). Здесь вы также можете удалить коммиты, но вам действительно нужно быть уверенным в том, что вы делаете, когда делаете это! Вилка Существует два основных подхода к совместной работе в репозиториях Git. Первый, подробно описанный выше, напрямую связан с ветками, которые люди тянут и толкают из / в. Эти соавторы имеют свои SSH-ключи, зарегистрированные в удаленном хранилище. Это позволит им напрямую перейти в этот репозиторий. Недостатком является то, что вы должны вести список пользователей. Другой подход - разветвление - позволяет любому «разветвлять» репозиторий, в основном делая локальную копию в своей учетной записи Git-репозитория. Затем они могут вносить изменения и по окончании отправлять «запрос на извлечение» (на самом деле это скорее «подталкивание» от них и «запрос на извлечение» для фактического сопровождающего репозитория), чтобы получить принятый код. Этот второй метод, использующий вилки, не требует, чтобы кто-то вел список пользователей для хранилища. GitHub

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

Когда вы «форкаете» - в графическом интерфейсе веб-браузера GitHub вы можете нажать на эту кнопку Image of fork button - вы создаете копию («клон») кода в вашей учетной записи GitHub. Когда вы делаете это в первый раз, это может быть немного незаметно, поэтому следите за тем, чтобы в чьем репозитории была указана база кода - либо у первоначального владельца, либо у пользователя «forked from», например:

Image of name of forked repository

Получив локальную копию, вы можете вносить изменения по своему усмотрению (вытягивая и отправляя их на локальный компьютер). Когда вы закончите, вы отправите «запрос на извлечение» первоначальному владельцу / администратору хранилища (звучит странно, но на самом деле вы просто нажимаете на это: Image of pull request button), и они «вытягивают» его.

Более распространенной для команды, работающей над кодом, является «клонирование» хранилища (щелкните значок «Копировать» на главном экране хранилища). Затем локально наберите git clone и вставьте. Это настроит вас локально, и вы также можете нажать и вытащить в (общее) местоположение GitHub.

Клоны

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

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

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

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

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

Image of gitg/gitx interface

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

Image of smart-git GUI

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

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

# git
alias g='git status'
alias gcob='git checkout -b '
alias gcom='git checkout master'
alias gd='git diff'
alias gf='git fetch'
alias gfrm='git fetch; git reset --hard origin/master'
alias gg='git grep '
alias gits='alias | grep "^alias g.*git.*$"'
alias gl='git log'
alias gl1='git log --oneline'
alias glf='git log --name-status'
alias glp='git log -p'
alias gpull='git pull '
alias gpush='git push '

И у меня есть следующие "git aliases" в моем файле ~/.gitconfig - почему они есть?
Так что завершение ветки (с клавишей TAB) работает!

Итак, это:

[alias]
  co = checkout
  cob = checkout -b

Пример использования: git co [branch] <- будет работать завершение вкладки для ветвей. </p>

GUI Learning Tool

Вы можете найти https://learngitbranching.js.org/ полезным для изучения некоторых базовых понятий. Снимок экрана: enter image description here
Видео: https://youtu.be/23JqqcLPss0

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

  1. Вы вносите изменения, добавляете и фиксируете их (но не нажимаете), а затем - о! вы понимаете, что вы мастер!

    git reset [filename(s)]
    git checkout -b [name_for_a_new_branch]
    git add [file(s)]
    git commit -m "A useful message"
    
    Voila!  You've moved that 'master' commit to its own branch !
    
  2. Вы испортили некоторые файлы, работая в локальном филиале, и просто хотите вернуться к тому, что у вас было в прошлый раз, когда вы git pull:

    git reset --hard origin/master  # You will need to be comfortable doing this!
    
  3. Вы начинаете вносить изменения локально, редактируете полдюжины файлов, а затем, о черт, вы все еще находитесь в основной (или другой) ветке:

    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
    
  4. Вы испортили один конкретный файл в своей текущей ветке и хотите просто "сбросить" этот файл (потерять изменения) на то, каким он был в последний раз, когда вы извлекали его из удаленного хранилища:

    git checkout your/directories/filename
    

    Это на самом деле сбрасывает файл (как и многие команды Git, он не совсем правильно назван для того, что он здесь делает).

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

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

    git rebase --abort # To abandon interactive rebase and merge issues
    
  7. Добавьте ветку Git в приглашение PS1 (см. https://unix.stackexchange.com/a/127800/10043), например,

    Image of prompt

    Ветка selenium_rspec_conversion.

359 голосов
/ 25 июля 2010

Клон - это просто копия хранилища. На первый взгляд, его результат эквивалентен 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, пожалуйста, посмотрите на комментарии, а также ответ Майкла Дарранта ниже моего для получения дополнительной информации.

142 голосов
/ 22 января 2013

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

enter image description here

7 голосов
/ 02 сентября 2016

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

Пожалуйста, см. Эту диаграмму . (Первоначально из 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')

Fork

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

Клон

  • копия в локальный репозиторий (жесткий диск)
6 голосов
/ 23 июля 2015

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

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

git clone $some_other_repo

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

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

Тем не менее,

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

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

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

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

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

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


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

...