Разрешение конфликтов git

Глава 3

Оглавление документа Применение Git в разработке

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

name = Your Name Comes Here

(См. Раздел “CONFIGURATION FILE” git-config(1) для получения дополнительных сведений о файле конфигурации.)

Создание нового репозитория с нуля очень просто:

Если у вас есть некоторое первоначальное наполнение (например, тарбол):

$ tar -xzvf project.tar.gz

$ git add . # Включить все ниже . в первый коммит

Создание нового коммита состоит из трех этапов:

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

2. Указание git`у о ваших изменениях.

3. Создание коммита, используя то, что вы указали git на втором шаге.

На практике вы можете можно интерактивно повторять 1 и 2 шаги столько раз, сколько хотите; чтобы отследить то, что вы хотите включить в коммит на шаге 3, git сохраняет отпечаток структуры изменённого содержания в специальной области «индекс» (index).

В начале, содержимое индекса будет идентично тому, что уже есть в HEAD. Команда “git diff – cached” показывает разницу между HEAD и индексом, поэтому нет смысла запускать её в этой точке.

Измененить индекс просто:

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

$ git add path/to/file

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

$ git add path/to/file

Для удаления файл из индекса и из рабочего дерева,

$ git rm path/to/file

После каждого шага можно проверить изменения :

$ git diff —cached

Команда git diff —cached всегда показывает разницу между HEAD и файлом индекса – это то, что попадает в проект, если вы сделаете коммит сейчас.

показывает разницу между рабочим деревом и файлом индекса. Заметьте, что “git add” всегда добавляет только текущие содержание файла индекса; дальнейшие изменения в один и тот же файл будут игнорироваться, если вы не запустите git-add ещё раз.

Когда все будет готово, просто запустите

и git даст приглашение для ввода сообщения о коммите и создаст новый коммит

Убедитесь, что это вы всё сделали правильно.

Cпециальная опция -a

обновляет индекс со всеми файлами, которые вы изменили, удалили или создали и создаёт коммит в один шаг.

Набор команд, полезных для отслеживания того, что Вы собираетесь зафиксировать коммитом:

$ git diff —cached # разница между HEAD и индексом, которая

# зафиксируется, если делать коммит сейчас

$ git diff # разница между индексом и вашим рабочим каталогом которые не

# зафиксируются, если делать коммит сейчас

$ git diff HEAD # разница между HEAD и рабочим каталогом, которая будет зафиксирована

# если сделать сейчас commit -a

$ git status # краткий суммарный отчёт о состоянии индекса, рабочего каталога и HEAD.

Вы также можете использовать git-gui(1) для создания коммита, просмотра изменений в индексе и в рабочем каталоге, индивидуально выбрать кусок изменений для включения в индекс (правым кнопкой мыши на кусок diff и выбрав пункт “Stage Hunk For Commit”).

Хотя это и не требуется, приветствуется стиль оформления сообщения о коммите в котором оно начинается со строки с кратким описанием изменений (менее 50 символа), а уже потом после пустуй строки подробным описанием изминений. Это позволяет превращать коммит в email – первую строку помещаем в тему письма, а остальное в его тело.

При работе с проект часто созжаются файлы, которые вы-бы не хотели отслеживать с помощью git. Это обычно файлы созданные процессом сборки и временные резервные копии файлов, созданных вашим редактором. Естественно, нет смысла отслеживать такие файлы и законно возникает вопрос – как сделать так, чтобы вызов “git add” не добавлял их. Отслеживание их быстро начинает раздражатью Из-за изменений этих файлов становятся практически бесполезны команды “git add .» и “git commit -a”, а изменения этих файлов засоряют вывод команды “git status”.

Вы можете указать git игнорировать определенные файлы, создав файл с именем .gitignore в верхнем уровне вашего рабочего каталога, например, с таким содержанием:

# Строки, начинающиеся с ‘#’ считаются комментариев.

# Игнорировать любой файл с именем foo.txt.

# Игнорировать (генерируются) html файлы,

# Кроме foo.html который включается в индекс вручную.

# Игнорировать файлы с расширением *.a и *.o

См. gitignore (5) для детального объяснения синтаксиса. Вы также можете разместить файлы .gitignore в другие каталоги вашего рабочего каталога, и они будут распространяться на эти каталоги и их подкаталоги. Файлы .gitignore могут быть добавлены в репозиторий подобно другим файлам (просто запустив git add .gitignore, как обычно), удобно также сделать так, что-бы при клонировании репозитория другими пользователями по этим шаблонам эти файлы исключались из копирования. Если вы хотите, чтобы исключающие шаблоны влияли только в некоторых репозиториях (вместо каждого репозитория для данного проекта), вы можете поместить шаюлоны в файл вашего репозитория с именем .git/info/exclude, или в файл, задаваемый значением переменной core.excludesfile вашей конфигурации.

Некоторые git команды могут также исключатm шаблоны непосредственно в командной строке. Подробнее см. man gitignore (5) .

Вы можете объединить две разделённые ветви разработки командой git-merge(1):

$ git merge branchname

при этом сливается ветка разработки “branchname» c текущей веткой. Если есть конфликты, например, если один и тот же файл изменяется двумя различными способами в удалённой ветке и в локальной ветке, вы будете предупреждены; вывод будет выглядеть примерно так:

CONFLICT (content): Merge conflict in file.txt

Automatic merge failed; fix conflicts and then commit the result.

# Конфликт (содержимого): Конфликт слияния в file.txt

# Автоматическое слияние с ошибкой; устраните конфликты, а затем включите результат

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

Если рассматривать результирующий коммит используя gitk, можно увидеть, что он имеет двух родителей один из которых вершина текущей ветки, а другой – вершина другой ветки.

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

file.txt: needs merge file.txt

#необходимо объединить file.txt

Кроме того, в git-status(1) будут перечислены эти файлы, как “unmerged” (необъединённые), а файлы с конфликтами будет помечены маркерами конфликта, например:

Все, что вам необходимо сделать, это отредактировать файлы для разрешения конфликтов, а затем дать команды

$ git add file.txt

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

Выше описоно всё, что вам необходимо знать для решения простых слияния.

Но git также может предоставить дополнительную информацию, чтобы помочь урегулировать более сложные конфликты:

7.1. Получение помощи при разрешения конфликтов слияния

Все изменения, которые git смог объединить автоматически уже добавлены в файл индекса, так что git-diff(1) показывает только конфликты. Используется особый синтаксис:

diff —cc file.txt

Напомним, что комммит, который будут зафиксирован после того, как мы урегулировали конфликт будет иметь двух родителей, а не одного: один из родителей будет HEAD – вершина текущей ветки; а другой будут вершиной другой ветви, значение которой временно сохраняется в переменной MERGE_HEAD. В ходе слияния, индекс содержит три версии каждого файла.

Каждая из этих трех «стадий файла» представляет различные версии файла:

$ git show :1:file.txt # файл в общий предке обеих ветвей

$ git show :2:file.txt # Версия HEAD, но и в том числе любое

# неконфликтное изменение из MERGE_HEAD

$ git show :3:file.txt # версия с MERGE_HEAD, но и в том числе любое

# не конфликтующее изменение от HEAD.

Начиная со стадии 2 и стадии 3 версии были обновлены с неконфликтными изменениями, и остающиеся разлияия между ними являются существенной для анализа слияния, и которую можно получить командой git-diff(1) для из индекса для показа этих оставшихся конфликтов.

Команда git diff показывает различия между версией рабочего каталога file.txt и версиями стадии 2 и стадии 3.

Таким образом заменяя в каждой строке один «+» или “-«, он теперь использует две колонки: первая колонка используется для различия между первым родителем и рабочий каталогом, а вторая отмечает различия между вторым родителем и рабочий каталогом. (См. “COMBINED DIFF FORMAT” раздела git-diff-files(1) для деталей формата.)

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

diff —cc file.txt

Здесь видно, что наше версия решение исключить “Hello world” от первого родителя, удалить “Goodbye” от второго родителя, и добавить: “Goodbye world”, которое ранее отсутствовало в обоих предках.

В некоторых особые опции diff позволяют находить различия рабочего каталога от любого из этих этапов:

$ git diff -1 file.txt # различий с этапом 1

$ git diff —base file.txt # как выше

$ git diff -2 file.txt # различий c этапом 2

$ git diff —ours file.txt # как выше

$ git diff -3 file.txt # различий c этапом 3

$ git diff —theirs file.txt # как выше.

Командами git-log(1) и gitk[1] также обеспечивается помощь при слиянии:

Они будут показывать все коммиты, которые существуют только в HEAD и в MERGE_HEAD, и которых касаются необъеденяемый файл.

Вы также можете использовать git-mergetool(1) которая позволяет объединить необъеденённые файлы с помощью внешних средств, таких как emacs или kdiff3.

Каждый раз, когда вы урегулировать конфликты в файле и обновляя индекс:

$ git add file.txt

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

Если вы не смогли слить ветви и решили просто отказаться и отказаться, вы всегда можете вернуться к состоянию до слияния :

$ git reset —hard HEAD

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

$ git reset —hard ORIG_HEAD

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

Существует один особый случай, не упомянутый выше, которая третируется по-разному. Нормально, результатом слияния является коммит слияния с двумя родителями, в точке объединения на двух линий разработки.

Однако, если текущая ветка является потомком другой и каждый коммит всегда один и всегда содержат коммит предыдущего, то можно просто выполнив команду git`ом “fast forward” (Быстрое движение вперёд) вершина текущей ветки продвинется вперед до точки вершины объединения в новую ветвь, без каких-либо новых созданий коммитов.

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

$ git reset —hard HEAD

Если вы сделаете коммит и позже вы решили отказаться от него, то у есть два принципиально различных способа решения проблемы:

  1. Вы можете создавать новые коммит, в котором отменить всё, что вы сделали в старом коммите. Это правильный вариант, если ваши ошибки уже были преданы гласности.
  2. Ни в коем случае не делайте этого, если вы уже сделали историю гласной; git обычно не ожидает изменения истоии проекта, и не может корректно выполнять частые слияния с веткой, у которой имело изменение истории. Напрример, от удаляемого вами коммита кто-то уже мог создать отдельную ветку разработки и такая ветка не сможет быть в дальнейшем корректно слита с вашим проектом.

Создание нового коммита, который отменяет ранее сделанные исправления, очень легко, просто дайте команду git-revert(1) с ссылкой на плохой коммит; например, вернуться к последниме коммиту:

$ git revert HEAD

Это позволит создать новыЙ коммит, который “откатывает” изменения HEAD. Вам будет предоставлена возможность отредактировать сообщение для совершения нового коммита.

Вы также можете вернуть последние изменения, например, предпоследние:

$ git revert HEAD^

В этом случае git попытается отменить старые изменения, оставляя нетронутыми любые изменения, сделанные после коммита.

Если последние изменения пересекаются с изменениями будет восстановления, Вам будет предложено устранить конфликты вручную, как и в случае удалени конфликтов a merge .

10.2. Исправление ошибки путём переписывания истории

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

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

$ git commit —amend

который заменит старый коммит новым путём включения ваших изменений, и давая вам возможность изменить вначале старое сообщение коммита.

Опять же, вы никогда не должны делать это с коммитом который уже был объединён в другую ветвь, в этом случае лучше использовать git-revert(1).

Кроме того, можно заменить более старые коммиты в истории, но это более сложная тема и мы оставим её его для другой главы.

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

$ git checkout HEAD^ path/to/file

заменяет содержимое указанного файла, и из коммита HEAD^, а также обновляет соответственно индекс. Команда не меняет текущую ветвь. Если вы просто хотите взглянуть на старую версию файла без изменения рабочего каталога, вы можете сделать git-show(1):

$ git show HEAD^:path/to/file

который будут отображён с учетом версии файла.

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

W – точка, где вы работали,

H — текущая HEAD,

I — точка коммита с исправлением выявленной тривиальной ошибки.

$ git stash “work in progress for foo feature”

Эта команда сохраняет все изменения “в тайнике” (stash), и возвращает рабочий каталог и индекс к HEAD. Затем вы можете исправить, тривиальную проблему и зафиксировать её решение.

. исправляем тривиальные ошибки .

$ git commit -a -m “blorpl: typofix”

После этого вы можете вернуться к тому, что вы делали до git stash командой:

$ git stash apply

Размер репозитории git зависит от сжатия сохранённой истории информации. Сжатие не даёт занять репозиторию слишком много места на диске и в памяти. Сжатие не выполняется автоматически. Поэтому вы должны периодически запускать git-gc(1) :

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

Команда git-fsck(1) запускает ряд логических самопроверок репозитория, и создаёт отчёт о всех имеющихся проблемах. Этот процесс может занять некоторое время. Наиболее распространенными это предупреждение о «зависших» объектах:

dangling commit 7281251ddd2a61e38657c827739c57015671a6b3

dangling commit 2706a059f258c6b245f298dc4ff2ccd30ec21a63

dangling commit 13472b7c4b80851a1bc551779171dcb03655e9b5

dangling blob 218761f9d90712d37a9c5e36f406f92202db07eb

dangling commit bf093535a34a4d35731aa2bd90fe6b176302f14f

dangling commit 8e4bec7f2ddaa268bef999853c25755452100f8e

dangling tree d50bb86186bf27b681d25af89d3b5b68382e4085

dangling tree b24c2473f1fd3d91352a624795be026d64c8841f

Зависание объектов не проблема. В худшем случае они бесполезно занимают место на диске. Они иногда могут стать последним средством в восстановлении потерянных наработок – см. Раздел “Dangling objects” для более детальной информации.

Скажем вы изменили ветвь git-reset(1) —hard а потом сообразили, что ветвь была была только ссылкой на точку в истории. К счастью, git также ведет журнал, называемый “reflog”, о всех предыдущих значений каждой ветви. Так что в этом случае вы все ещё можете найти старую историю, используя, например,

Эта команда выдаёт список коммитов о предыдущего версиях вершины ветки “master”. Cинтаксис может быть использован с любыми командами git, которые принимают коммит, а не только с git log. Некоторые примеры:

$ git show master@ <2># Смотрим где ветвь указывает 2,

$ git show master@ <3># 3, . изменения назад.

$ gitk master@ # Смотрим что изменилось вчера,

$ gitk master@ <"1 week ago"># . неделю назад

$ git log —walk-reflogs master # смотрим содержимое reflog ветки master

Посмотреть reflog сохранённый в HEAD, можно так

Команда покажет, на что указывало HEAD неделю назад, а не то, что текущая ветвь указала неделю назад. Это позволяет просматривать историю о том, с чем вы работали .

Reflogs хранятся по умолчанию в течение 30 дней, после чего он будет обрезан. См. git-reflog(1) и git-gc(1) чтобы узнать, как управлять этим обрезанием, и смотрите секцию &#8220;SPECIFYING REVISIONS&#8221; git-rev-parse(1) для изучения подробностей.

Заметьте, что reflog история сильно отличантся от обычной истории git истории.

Обычная история отражает совместное использование репозитория всех, кто работает с этим проектом, а reflog история локальна: она говорит вам лишь о том, какие ветки в локальном репозитории были изменены и в какой момент времени.

В некоторых ситуациях reflog, возможно, не сможет вам помочь.

Например, предположим, вы удалили ветвь, в истории которой содержался необходимый вам релиз. Reflog также был удалён, однако, если вы еще не очищали от мусора репозиторий, то вы по-прежнему ещё можете найти потерянный вами коммит в зависших объектах, о которых вам сообщает команда git-fsck.

См. раздел &#8220;Dangling objects&#8221; для изучения деталей.

dangling commit 7281251ddd2a61e38657c827739c57015671a6b3

dangling commit 2706a059f258c6b245f298dc4ff2ccd30ec21a63

dangling commit 13472b7c4b80851a1bc551779171dcb03655e9b5

Вы можете изучить любой из этих зависших коммитов, например дав команду:

$ gitk 7281251ddd —not —all

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

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

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

$ git branch recovered-branch 7281251ddd

Другие виды зависших объектов (blobs и trees), так-же могут существовать, и эти зависшие объекты могут возникать в разных ситуациях.

Источник:
Глава 3
Оглавление документа Применение Git в разработке Прежде чем что-нибудь создавать и коммитить, вы должны представиться git. Простейший способ сделать это состоит в том, чтобы убедиться, что
http://freesource.info/wiki/RuslanHihin/gitusermanual/Chapter3/watch

Записки программиста

28 декабря 2011

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

Главное отличие Git от Subversion заключается в том, что Git &#8212; распределенная система контроля версий. Звучит ужасающе, но на практике это означает очень простую вещь. Каждый разработчик держит у себя на диске отдельный репозиторий. Обратите внимание &#8212; не копию репозитория, не некоторые бранчи, а тупо отдельный и при этом абсолютно полноценный репозиторий.

Пока мы работаем в рамках своего репозитория, все происходит в точности, как в Subversion. Мы коммитим и откатываем изменения, создаем, мержим и удаляем бранчи, разрешаем конфликты и тд. Помимо этого, предусмотрены команды для работы с репозиториями на удаленных машинах. Например, «git push» означает мерж локальных изменений в удаленный репозиторий, а «git pull» &#8212; наоборот, мерж изменений из удаленного репозитория в локальный. Обмен данными по сети обычно происходит с использованием протокола SSH.

В результате имеем:

Я использовал Git при написании программы из заметки Генерация почти осмысленных текстов на Haskell, сидя под своей любимой FreeBSD. Вот как примерно выглядела моя работа с Git.

В первую очередь необходимо поставить Git:

Затем создаем пару ssh ключей, если не создавали ее ранее:

Источник:
Записки программиста
Некоторое время назад я открыл для себя Git. И знаете, я проникся. То есть, по-настоящему проникся. Теперь я использую Git не только на работе (где я с ним, соб
http://eax.me/git-commands/

Разрешение конфликтов git

Шаг 1. имеем файл 1.txt с таким содержанием (две пронумерованные строки)

Шаг 2. делаем отдельную Ветку &quot;тест&quot; и правим строку 1 пишем туда слово first , комитим

Шаг 3. возвращаемся в ветку &quot;мастер&quot; и правим файл дописывая во вторую строку слово second и коммитим

Шаг 4. возвращаемся в ветку &quot;Тест&quot; и делаем

&#60;&#33;— Author: Marina Pushkova (marina@githowto.com) —&#62;

&#60;&#33;— Author: Marina Pushkova (marina@githowto.com) —&#62;

у автора старая версия ГИТа?

на самом деле там увидеть проблему нереально. Надо смотреть как минимум вывод различий

Смоделировал первый пример — выдал конфликт, как я и ожидал.

Пробежался по этому howto — как-то уж совсем сухо и без пояснений, хотя местами это очень критично.

Это проект знакомого я как раз его изучаю детально.

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

лучше подробнее остановиться на описании параметрах reset: —hard, —soft, —mixed. Стандартная справка бывает не всем понятна.

Здесь кратко о ssh: Если у человека есть опыт работы с ssh-сервером, то ему достаточно обеспечить доступ к катологу с репозиториями через протокол (т.е. примерно как с sftp) и (желательно, но необязательно) проходить авторизацию через пользователя у которого в качестве оболочки установлена git-shell.

Источник:
Разрешение конфликтов git
Шаг 1. имеем файл 1.txt с таким содержанием (две пронумерованные строки) Шаг 2. делаем отдельную Ветку &quot;тест&quot; и правим строку 1 пишем туда слово first , комитим Шаг 3.
http://forum.sources.ru/index.php?showtopic=334860

Разрешение конфликтов git

Git (произн. «гит») — распределённая система управления версиями файлов. Проект был создан Линусом Торвальдсом для управления разработкой ядра Linux. На сегодняшний день поддерживается Джунио Хамано.

Система спроектирована как набор программ, специально разработанных с учётом их использования в скриптах. Это позволяет удобно создавать специализированные системы контроля версий на базе Git или пользовательские интерфейсы. Например, Cogito является именно таким примером фронтенда к репозиториям Git, а StGit использует Git для управления коллекцией патчей.

Git поддерживает быстрое разделение и слияние версий, включает инструменты для визуализации и навигации по нелинейной истории разработки. Как и Darcs, BitKeeper, Mercurial, SVK, Bazaar и Monotone, Git предоставляет каждому разработчику локальную копию всей истории разработки; изменения копируются из одного репозитория в другой.

Удалённый доступ к репозиториям Git обеспечивается git-daemon, gitosis, SSH- или HTTP-сервером. TCP-сервис git-daemon входит в дистрибутив Git и является наряду с SSH наиболее распространённым и надёжным методом доступа. Метод доступа по HTTP, несмотря на ряд ограничений, очень популярен в контролируемых сетях, потому что позволяет использовать существующие конфигурации сетевых фильтров.

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

Клонируем репозиторий, используя протокол http:

Клонируем репозиторий с той же машины в директорию myrepo :

Клонируем репозиторий, используя безопасный протокол ssh:

У git имеется и собственный протокол:

Импортируем svn репозиторий, используя протокол http:

git fetch и git pull — забираем изменения из центрального репозитория¶

Для синхронизации текущей ветки с репозиторием используются команды git fetch и git pull.

git fetch — забрать изменения удаленной ветки из репозитория по умолчания, основной ветки; той, которая была использована при клонировании репозитория. Изменения обновят удаленную ветку (remote tracking branch), после чего надо будет провести слияние с локальной ветку командой git merge.

git fetch /home/username/project — забрать изменения из определенного репозитория.

Возможно также использовать синонимы для адресов, создаваемые командой git remote :

git fetch username-project — забрать изменения по адресу, определяемому синонимом.

Естественно, что после оценки изменений, например, командой git diff , надо создать коммит слияния с основной:

Команда git pull сразу забирает изменения и проводит слияние с активной веткой.

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

Забрать изменения и метки из определенного репозитория:

Как правило, используется сразу команда git pull .

git push — вносим изменения в удаленный репозиторий¶

После проведения работы в экспериментальной ветке, слияния с основной, необходимо обновить удаленный репозиторий (удаленную ветку). Для этого используется команда git push.

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

Отправить изменения из ветки master в ветку experimental удаленного репозитория:

В удаленном репозитории origin удалить ветку experimental:

В удаленную ветку master репозитория origin (синоним репозитория по умолчанию) ветки локальной ветки master:

Отправить метки в удаленную ветку master репозитория origin:

Изменить указатель для удаленной ветки master репозитория origin (master будет такой же как и develop)

Добавить ветку test в удаленный репозиторий origin, указывающую на коммит ветки develop:

Команда git init создает в директории пустой репозиторий в виде директории .git , где и будет в дальнейшем храниться вся информация об истории коммитов, тегах — о ходе разработки проекта:

Следующее, что нужно знать — команда git add . Она позволяет внести в индекс — временное хранилище — изменения, которые затем войдут в коммит. Примеры использования:

индексация измененного файла, либо оповещение о создании нового:

внести в индекс все изменения, включая новые файлы:

Из индекса и дерева проекта одновременно файл можно удалить командой git rm :

хороший пример удаления из документации к git, удаляются сразу все файлы txt из папки:

внести в индекс все удаленные файлы:

Сбросить весь индекс или удалить из него изменения определенного файла можно

командой git reset :

сбросить весь индекс:

удалить из индекса конкретный файл:

Команда git reset используется не только для сбрасывания индекса, поэтому дальше

ей будет уделено гораздо больше внимания.

git status — состояние проекта, измененные и не добавленные файлы, индексированные файлы

Команду git status , пожалуй, можно считать самой часто используемой наряду с

командами коммита и индексации. Она выводит информацию обо всех изменениях,

внесенных в дерево директорий проекта по сравнению с последним коммитом рабочей

ветки; отдельно выводятся внесенные в индекс и неиндексированные

файлы. Использовать ее крайне просто:

Кроме того, git status указывает на файлы с неразрешенными конфликтами слияния и

файлы, игнорируемые git.

Коммит — базовое понятие во всех системах контроля версий, поэтому совершаться

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

после индексации набрать:

Если индекс не пустой, то на его основе будет совершен коммит, после чего

пользователя попросят прокомментировать вносимые изменения вызовом команды

edit . Сохраняемся, и вуаля! Коммит готов.

Есть несколько ключей, упрощающих работу с git commit :

совершит коммит, автоматически индексируя изменения в файлах проекта. Новые файлы при этом индексироваться не будут! Удаление же файлов будет учтено.

комментируем коммит прямо из командной строки вместо текстового редактора.

внесет в индекс и создаст коммит на основе изменений единственного файла.

git reset — возврат к определенному коммиту, откат изменений, «жесткий» или «мягкий»

Помимо работы с индексом (см. выше), git reset позволяет сбросить состояние проекта до какого-либо коммита в истории. В git данное действие может быть двух видов: «мягкого»(soft reset) и «жесткого» (hard reset).

«Мягкий» (с ключом —soft ) резет оставит нетронутыми ваши индекс и все дерево файлов и директорий проекта, вернется к работе с указанным коммитом. Иными словами, если вы обнаруживаете ошибку в только что совершенном коммите или комментарии к нему, то легко можно исправить ситуацию:

  1. git commit — некорректный коммит
  2. git reset —soft HEAD^ — переходим к работе над уже совершенным коммитом, сохраняя все состояние проекта и проиндексированные файлы
  3. edit WRONGFILE
  4. edit ANOTHERWRONGFILE
  5. git add .
  6. git commit -c ORIG_HEAD — вернуться к последнему коммиту, будет предложено редактировать его сообщение. Если сообщение оставить прежним, то достаточно изменить регистр ключа -с:

Обратите внимание на обозначение HEAD^, оно означает «обратиться к предку последнего коммита». Подробней описан синтаксис такой относительной адресации будет ниже, в разделе «Хэши, тэги, относительная адресация». Соответственно, HEAD — ссылка на последний коммит. Ссылка ORIG_HEAD после «мягкого» резета указывает на оригинальный коммит.

Естественно, можно вернуться и на большую глубину коммитов,

«Жесткий» резет (ключ —hard ) — команда, которую следует использовать с

осторожностью. git reset —hard вернет дерево проекта и индекс в состояние,

соответствующее указанному коммиту, удалив изменения последующих коммитов:

Если команда достигнет точки ветвления, удаления коммита не произойдет.

Для команд слияния или выкачивания последних изменений с удаленного репозитория

примеры резета будут приведены в соответствующих разделах.

git revert — отмена изменений, произведенных в прошлом отдельным коммитом

Возможна ситуация, в которой требуется отменить изменения, внесенные отдельным коммитом. git revert создает новый коммит, накладывающий обратные изменения.

Отменяем коммит, помеченный тегом:

Отменяем коммит, используя его хэш:

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

git log — разнообразная информация о коммитах в целом

Иногда требуется получить информацию об истории коммитов; коммитах, изменивших

отдельный файл; коммитах за определенный отрезок времени и так далее. Для этих

целей используется команда git log .

Простейший пример использования, в котором приводится короткая справка по всем

коммитам, коснувшимся активной в настоящий момент ветки (о ветках и ветвлении

подробно узнать можно ниже, в разделе «Ветвления и слияния»):

Получить подробную информацию о каждом в виде патчей по файлам из коммитов

можно, добавив ключ -p (или -u):

Статистика изменения файлов, вроде числа измененных файлов, внесенных в них

строк, удаленных файлов вызывается ключом —stat :

За информацию по созданиям, переименованиям и правам доступа файлов отвечает ключ

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

его имя (кстати, в моей старой версии git этот способ не срабатывает,

обязательно добавлять » — » перед «README»):

или, если версия git не совсем свежая:

Далее будет приводится только более современный вариант синтаксиса. Возможно

указывать время, начиная в определенного момента («weeks», «days», «hours», «s»

изменения, касающиеся отдельной папки:

Можно отталкиваться от тегов.

Все коммиты, начиная с тега v1:

Интересные возможности по формату вывода команды предоставляет ключ —pretty .

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

В принципе, формат вывода можно определить самостоятельно:

Определение формата можно поискать в разделе по git log из Git Community Book

или справке. Красивый ASCII-граф коммитов выводится с использованием ключа

git diff — отличия между деревьями проекта, коммитами и т.д.

Своего рода подмножеством команды git log можно считать команду git diff ,

определяющую изменения между объектами в проекте — деревьями (файлов и

Показать изменения, не внесенные в индекс:

git show — показать изменения, внесенные отдельным коммитом

Посмотреть изменения, внесенные любым коммитом в истории, можно командой git show :

git blame и git annotate — команды, помогающие отслеживать изменения файлов

При работе в команде часто требуется выяснить, кто именно написал конкретный

код. Удобно использовать команду git blame , выводящую построчную информацию о

последнем коммите, коснувшемся строки, имя автора и хэш коммита:

Можно указать и конкретные строки для отображения:

Аналогично работает команда git annotate , выводящая и строки, и информацию о

коммитах, их коснувшихся:

git grep — поиск слов по проекту, состоянию проекта в прошлом

git grep , в целом, просто дублирует функционал знаменитой юниксовой

команды. Однако он позволяет слова и их сочетания искать в прошлом проекта, что

бывает очень полезно.

Поиск слова tst в проекте:

Подсчитать число упоминаний tst в проекте:

Поиск в старой версии проекта:

Команда позволяет использовать логическое И и ИЛИ.

Найти строки, где упоминаются и первое слово, и второе:

Найти строки, где встречается хотя бы одно из слов:

git branch — создание, перечисление и удаление веток

Работа с ветками — очень легкая процедура в git, все необходимые механизмы сконцентрированы в одной команде:

Просто перечислить существующие ветки, отметив активную:

git checkout — переключение между ветками, извлечение файлов

Команда git checkout позволяет переключаться между последними коммитами (если упрощенно) веток:

Создаст ветку, в которую и произойдет переключение

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

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

Вернуть файл (или просто вытащить из прошлого коммита) позволяет команда вида:

Вернуть somefile к состоянию последнего коммита:

Вернуть somefile к состоянию на два коммита назад по ветке:

git merge — слияние веток (разрешение возможных конфликтов)

Слияние веток, в отличие от обычной практики централизованных систем, в git происходит практически каждый день. Естественно, что имеется удобный интерфейс к популярной операции.

Попробовать объединить текующую ветку и ветку new-feature:

В случае возникновения конфликтов коммита не происходит, а по проблемным файлам расставляются специальные метки а-ля svn; сами же файлы отмечаются в индексе как «не соединенные» (unmerged). До тех пор пока проблемы не будут решены, коммит совершить будет нельзя.

Например, конфликт возник в файле TROUBLE , что можно увидеть в git status .

Произошла неудачная попытка слияния:

Смотрим на проблемные места:

Индексируем наши изменения, тем самым снимая метки:

Совершаем коммит слияния:

Вот и все, ничего сложного. Если в процессе разрешения вы передумали разрешать конфликт, достаточно набрать (это вернёт обе ветки в исходные состояния):

Если же коммит слияния был совершен, используем команду:

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

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

Предположим, имеется две ветки, master и topic, в каждой из которых было совершенно несколько коммитов начиная с момента ветвления. Команда git rebase берет коммиты из ветки topic и накладывает их на последний коммит ветки master.

Вариант, в котором явно указывается, что и куда накладывается:

на master накладывается активная в настоящий момент ветка:

После использования команды история становится линейной. При возникновении конфликтов при поочередном накладывании коммитов работа команды будет останавливаться, а в проблемные местах файлов появятся соответствующие метки. После редактирования — разрешения конфликтов — файлы следует внести в индекс командой git add и продолжить наложение следующих коммитов командой git rebase —continue . Альтернативными выходами будут команды git rebase —skip (пропустить наложение коммита и перейти к следующему) или git rebase —abort (отмена работы команды и всех внесенных изменений).

С ключом -i ( —interactive ) команда будет работать в интерактивном режиме. Пользователю будет предоставлена возможность определить порядок внесения изменений, автоматически будет вызывать редактор для разрешения конфликтов и так далее.

git cherry-pick — применение к дереву проекта изменений, внесенных отдельным коммитом

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

Изменения, внесенные указанным коммитом будут применены к дереву, автоматически проиндексированы и станут коммитом в активной ветке:

Ключ -n показывает, что изменения надо просто применить к дереву проекта без индексации и создания коммита

В git для идентификации любых объектов используется уникальный (то есть с огромной вероятностью уникальный) хэш из 40 символов, который определяется хэшируюшей функцией на основе содержимого объекта. Объекты — это все: коммиты, файлы, тэги, деревья. Поскольку хэш уникален для содержимого, например, файла, то и сравнивать такие файлы очень легко — достаточно просто сравнить две строки в сорок символов.

Больше всего нас интересует тот факт, что хэши идентифицируют коммиты. В этом смысле хэш — продвинутый аналог ревизий Subversion. Несколько примеров использования хэшей в качестве способа адресации:

найти разницу текущего состояния проекта и коммита за номером… сами видите, каким:

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

Иногда хватает и четырех символов:

Читаем лог с коммита по коммит:

Разумеется, человеку пользоваться хэшами не так удобно, как машине, именно поэтому были введены другие объекты — тэги.

git tag — тэги как способ пометить уникальный коммит

Тэг (tag) — это объект, связанный с коммитом; хранящий ссылку на сам коммит, имя автора, собственное имя и некоторый комментарий. Кроме того, разработчик может оставлять на таких тегах собственную цифровую подпись.

Кроме этого в git представленные так называемые «легковесные тэги» (lightweight tags), состоящие только из имени и ссылки на коммит. Такие тэги, как правило, используются для упрощения навигации по дереву истории; создать их очень легко.

Создать «легковесный» тэг, связанный с последним коммитом; если тэг уже есть, то еще один создан не будет:

Пометить определенный коммит:

Создать тэг для последнего коммита, заменить существующий, если таковой уже был:

После создания тэга его имя можно использовать вместо хэша в любых командах вроде git diff , git log и так далее:

Обычные тэги имеет смысл использовать для приложения к коммиту какой-либо информации, вроде номера версии и комментария к нему. Иными словами, если в комментарии к коммиту пишешь «исправил такой-то баг», то в комментарии к тэгу по имени «v1.0» будет что-то вроде «стабильная версия, готовая к использованию».

Создать обычный тэг для последнего коммита; будет вызван текстовый редактор для составления комментария:

Создать обычный тэг, сразу указав в качестве аргумента комментарий:

Команды перечисления, удаления, перезаписи для обычных тэгов не отличаются от команд для «легковесных» тэгов.

Вместо ревизий и тэгов в качестве имени коммита можно опираться на еще один механизм — относительную адресацию. Например, можно обратиться прямо к предку последнего коммита ветки master:

Если после «птички» поставить цифру, то можно адресоваться по нескольким предкам коммитов слияния:

найти изменения по сравнению со вторым предком последнего коммита в master; HEAD здесь — указатель на последний коммит активной ветки:

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

что привнес «дедушка» нынешнего коммита:

Обозначения можно объединять, чтобы добраться до нужного коммита:

файл .gitignore — объясняем git, какие файлы следует игнорировать

Иногда по директориям проекта встречаются файлы, которые не хочется постоянно видеть в сводке git status . Например, вспомогательные файлы текстовых редакторов, временные файлы и прочий мусор.

Заставить git status игнорировать определенные файлы можно, создав в корне или глубже по дереву (если ограничения должны быть только в определенных директория) файл .gitignore . В этих файлах можно описывать шаблоны игнорируемых файлов определенного формата.

Пример содержимого такого файла:

Существуют и другие способы указания игнорируемых файлов, о которых можно узнать из справки git help gitignore .

; git update-server-info : Команда создает вспомогательные файлы для dumb-сервера в $GIT_DIR/info и $GIT_OBJECT_DIRECTORY/info каталогах, чтобы помочь клиентам узнать, какие ссылки и пакеты есть на сервере.

; git count-objects : Проверка, сколько объектов будет потеряно и объём освобождаемого места при перепаковке репозитория.

; git gc : Переупаковка локального репозитория.

Создание пустого репозитория на сервере

Импорт svn репозитория на Git-сервер

Источник:
Разрешение конфликтов git
Redmine
http://www.calculate-linux.ru/main/ru/git

(Visited 8 times, 1 visits today)

CATEGORIES