Подробное руководство по Git

Mar 26, 2018

Основные сообщения в консоли:

  • checkout - выгрузка;
  • Untracked file - не отслеживаемый файл; git видит файл, но он отсутствует в предыдущем снимке состояний (коммит); подобный подход гарантирует, что в репозитории не окажется случайных файлов. Такие файла необходимо добавить в индекс командой git add.
  • Changes to be committed - все проиндексированные файл идут под этим заголовком.
  • Changes not staged for commit - отслеживаемый файл изменен, но пока не проиндексирован.
  • Changes but not updated - после удаления файла; измененные, но не проиндексированные
  • fast forward (перемотка) - возникает при слиянии веток, указывает на то, что изменений требующих объединений нет; другими словами объединяется ветка-родитель и ветка-потомок
  • unmerged (необъединенное) - обычно возникает при конфликтах
  • master d16556e [origin/master: ahead 1] comment - ahead 1 - наличие 1-го локально коммита, который пока не отправлен на сервер; behind 1 - на сервере есть 1 коммит, который пока не слит.
  • pull request - запрос на включение.

Снимки состояний как основа

Большинство систем хранят информацию как список изменений, связанных с файлами (Subversion).

GIT же делает снимок файлов в конкретный момент времени и сохраняется ссылка на этот снимок. Для увелечения эффективности на неизмененные файлы делается ссылка на их раннее сохраненные версии.

Контрольная сумма

Контрольная сумма - хеш SHA-1, git сохраняет данные по хешу.

3 состояния для файлов

Файлы в GIT могут находиться в 3 состояниях:

  • Модифицированные (modified) - изменения есть, но в локальную БД не внесены.
  • Индексированные (staged) - модифицированные файлы, при этом помечены как готовые для фиксации.
  • Зафиксированные (commited) - данные сохранены в локальной БД.

Как строится процесс работы в Git

  • 1. Редактируем файлы
  • 2. Индексируем файлы, при это снимки файлов добавляются в область индексирования
  • 3. Фиксация. Из области индексирования файлы сохраняются в папке Git

Настройки

Переменные конфигурации Git хранятся на windows в файле C:users\$USER\.gitconfig. .gitconfig каждого конкретного репозитория приоритетен.

Команды

git config

Данную информацию следует указать обязательно, так как она будет включаться во все ваши коммиты:

git config –global user.name "firstName  lastName"
git config –global user.email "email@mail.ru"

Git позволяет ставить настройки общесистемные (--system), на уровне конкретного пользователя (--global), на уровне проекта (--local).

Проверка настроек

git config --list

Узнаем подробности о том, как работает команда, например, log:

git help [команда]
git help log

Пример файла .git/config

[user]
    name = name_user
    email = mail_user@mail.ru
[push]
    default = matching
[http]
    postBuffer = 524288000
[alias]
    st = status
    ci = commit
    br = branch
    co = checkout
    df = diff
    lg = log -p

Псевдонимы (алиасы) в GIT

Команда git config позволяет создавать псевдонимы:

git config --global alias.st status
git config --global alias.ci commit
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'

.gitignore

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

Игнорируем имена файлов:

npm-debug.log
.DS_Store

Звезда означает фрагмент в имени:

*.launch

Указываем диапозон (для игнорирования файлов):

project-201[4-7]*

? - означает ровно 1 произвольный символ (который обязателен):

.ло?

Если нужно игнорировать директорию, то ставим в конце имени директории /, при этом будет игнорироваться любая директория, а не только корневая:

build/

Игнорируем от корня проекта:

/build/

При этом данные конструкции работают одинаково:

/build/key
build/key

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

**/*.txt

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

/folder/*
!folder/package.json

Проверяем состояние файла в .gitignore:

git check-ignore -v folder/package.json

Жизненный цикл состояния файлов

Основные команды в Git

git init

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

git init

Будет создана папка /.git/. Репозиторий - это скрытая папка, в которой работает Git.

По умолчанию команда git init создает ветку master.

git clone

git clone [git url]

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

Предварительно необходимо выполнить команду git init.

mkdir epicgame & cd epicgame
git init
git clone [git url]
git clone [git url] [name_folder]

Эта команда аналогично предыдущей, но все файлы перемещаются в папку [name_folder]

git status

Команда, показывающая статус репозитория, чтобы увидеть в каком состоянии находится наш проект:

git status

Получаем сведения в более компактной форме при помощи флага -s (--short):

git status -s
git status --short
  • ?? - новые неотслеживаемые файлы
  • A - файлы добавлены в область предварительной подготовки
  • M - модифицированные

git add (Отслеживание новых файлов)

Данная команда может работать как "Добавление файлов к проекту" (добавляем в индекс).

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

git add [name_file]

Если вы снова выполните команду status, то увидите, что файл [name_file] теперь отслеживаемый и индексированный.

Флаг --force позволяет принудительно добавить что-то в индекс, даже несмотря на то что это что-то может находиться в .gitignore.

git add --force folder/text.txt

git add (Индексация изменённых файлов)

Также данная команда может работать как "Добавление содержимого к следующему коммиту".

Давайте модифицируем файл, уже находящийся под версионным контролем. Чтобы проиндексировать его, необходимо выполнить команду:

git add [name_file]

git --all или git -a

Флаг --all или -a укажет на то, что необходимо взять все изменения из рабочей директории, внести их в индекс (git add) и тут же закоммитить в репозиторий. Но -a игнорирует файлы, который не отслеживаются git (untracked file).

git commit -a -m "comment"
git commit -am "comment"

git reset (Отмена индексирования)

Индексируем:

git add *

Примечательно, что команда git status покажет, как отменить индексирование:

Changes to be committed:
(use "git reset HEAD [file]..." to unstage)

Отменим индексирование:

git reset HEAD *

Или сбросим изменения в индексе для каталога .idea (служебный каталог webstorm)

git reset HEAD .idea

git commit

Фиксируем изменения:

git commit -m "my comment"

Флаг -m позволяет задать сообщение фиксации.

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

Флаг -a позволяет автоматически индексировать все отслеживаемые файлы перед их фиксацией.

git commit -a -m "my comment"

git rm

Команды git rm, которая не только удалит файлы с диска, но и добавит сведения об их удалении в Git.

git rm '*.txt'

Чтобы удалить директорию:

git rm -r src

Если вы проиндексировали файл, то следует воспользоваться параметром -f, который инициирует принудительное удаление ( файл будет удален как из рабочей директории, так и из индекса).

git rm -f index.html

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

git rm --cached [name_file]

git amend (Изменение последнего коммита)

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

git add .

Далее закоммитить изменения с параметром --amend:

git commit --amend

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

Чтобы изменить название коммита выполните:

git commit --amend -m "new name commit"

git checkout (Отмена изменение в файле)

С подсказкой опять поможет команда git status:

use "git checkout -- [file]..." to discard changes in working directory

Отметьте, что все что после -- воспринимается как путь.

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

git checkout -- [name_file]

git checkout (Получаем предыдущие версии файлов, не трогая остальные)

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

Восстановим файл index.html на момент конкретного коммита (0b335):

git checkout 0b335 index.html

Или откатим версию файла до состояния из текущего коммита (откатим изменения, которые нас не устраивают):

git checkout HEAD index.html

Что аналогично:

git checkout index.html

git clone

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

Кроме того при клонировании git автоматически настраивает локальную ветку master на слежение за удаленной веткой master.

Очистка проекта от всех изменений (git clean)

Иногда требуется очистить рабочую директорию от незакомиченных изменений. Например, команда git reset --hard не затронет непроиндексированные файлы (то есть те файлы за которыми git не следит - Untracked files).

Команда git clean предназначена для удаления только неотслеживаемых файлов и директорий

git clean -dxf

Флаги:

  • -d - удалит не только флаги, но и директории.
  • -dx- x удалит в том числе файлы, которые игнорируются через .gitignore
  • -dxf - f указывает, что мы понимаем, что делаем

Просмотр (diff)

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

Сравниваем с текущим состоянием

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

git diff HEAD

git diff сравнивает рабочую директорию с индексом, то есть если добавить файл в индекс (git add test.html), то команда git diff ничего не выведет (в отличие от git diff HEAD, которая сравнивает с тем, что сохранено в репозитории).

git diff

Но при этом обе приведенные выше команды игнорируют неотслеживаемые файлы.

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

git diff --staged

Аналогично:

git diff --cached

Ограничим сравнение по пути:

git diff ... -- paths

Сравним состояние 2-х коммитов

сравним по хешам:

git diff 34sd 54sd

Сравним состояние 2-х веток

сравним, что сделано в feature по сравнению с веткой master:

git diff master feature

аналогично

git diff master..feature

Но если нам надо определить, что именно изменилось в feature с момента ее расхождения от master, то необходимо использовать ...:

git diff master...feature

Сравниваем файлы из разных коммитов

git diff commit1:path1 commit2:path2

Сравнение по словам

Чтобы включить отличия по словам:

git diff --word-diff

Удаленный репозиторий

git remote (прсматриваем уд. реп.)

Команда git remote позволяет просмотреть удаленные репозитории

git remote -v

параметр -v позволяет увидеть URL-адреса.

git remote add (добавляем уд. реп., для работы локально)

Добавление удаленных репозиториев под коротким именем:

git remote add [сокращенное имя] [url]
git remote add alias_repo [url]

- теперь вместо полного URL-адреса в командную строку можно вводить имя alias_repo

В уже сущест. реп. добавляем реп. сторонний и стягиваем из него ветку master:

git remote add interview https://github.com/asdasd/interview.git
git pull interview master

Пример использования:

  • Иниц. пустой реп.
  • Добавляем реп.
  • извлекаем все данные (.git)
  • и стягиваем ветку master из реп. kuku
git init
git remote add kuku https://github.com/denzLLL/test.git
git fetch kuku
git pull kuku master

git fetch (Извлечение данных из уд. реп.)

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

git fetch [имя уд. реп.]

После исполнения данной команды у вас должны появиться ссылки на все ветки удаленного проекта.

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

git fetch origin

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

$ git pull

git push (проталкиваем изменения на уд. сервер)

Отправляем изменения в удаленный репозиторий:

git push [имя удаленного репозитория] [ветка]

Отправим ветку master на удаленный репозиторий master:

git push origin master

Или, что тоже самое:

git push origin master:master
git push -u origin master

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

Отправим ветку master на удаленный репозиторий masterB:

git push origin master:masterB

Посредством : разделяем локальную ветку master и удаленную ветку masterB.

git push (удаляем удаленные ветки)

Удаляем ветку в удаленном репозитории:

git push origin --delete [ветка]

git pull (скачиваем изменения)

git pull выполняет по сути команды git fetch и git merge. Если ветка настроена на наблюдение, то обращение будет к ветке на сервере, за которой наблюдает текущая ветка.

git remote show (получаем инфо. об уд. реп.)

Команда git remote show [имя удал. реп.] позволяет просмотреть дополнительную информацию о конкретном удал. реп., включая удаленные ветки, локальные ветки, а также настройки для git pull и git push.

git remote show [имя удал. реп.]
git remote show origin

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

Удаленные ветки

Удаленные ветки - это ссылки на состояние веток в удаленных репозиториях.

Структура наименования удаленной ветки - (имя удаленного репозиория)/ветка. Например, origin/master.

Если вам потребуется своя локальная ветка (name_branch), аналогичная удаленной ветки, то можно воспользоваться командой:

git checkout -b name_branch origin/name_branch

Этим мы также говорим, что ветка name_branch следит за удаленной веткой origin/name_branch.

Данную операцию можно реализовать при помощи параметра --track:

git checkout --track origin/name_branch

Будет создана локальная ветка name_branch, которая следит за удаленной веткой origin/name_branch.

Или создадим локальную ветку, чье имя будет отличаться от имени удаленной ветки:

git checkout -b test-master origin/master

Локальная ветка test-master 'смотрит' на удаленную ветку origin/master.

Если вам потребуется поменять удаленную ветку, за которой вы следите, используйте параметр -u или --set-upstream-to команды git branch:

git branch -u origin/test-git

Текущая ветка начнет следить за удаленной origin/test-git

Параметр -vv позволяет увидеть ветки наблюдения (локальная информация):

git branch -vv

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

git fetch --all
git branch -vv

Ветвление

Ветки в Git всего лишь указатели на предыдущие коммиты, перед каждым коммитом указатель автоматически сдвигается вперед.

git branch (создаем ветку)

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

git branch [name_branch]

Указатель HEAD указывает на текущую локальную ветку.

Узнаем указатели веток:

git log --decorate --oneline

Обратите внимание. Узнаем указатели веток, историю коммитов, точки расхождения:

git log --decorate --oneline --graph --all

git branch -d (удаление ветки)

Удалим ветку:

git branch -d clean_up

git branch (управление ветками)

Отобразим все ветки:

git branch

* указывает на ветку с указатедем HEAD(текущая).

Отобразим ветку с информацией о коммите:

git branch -v

Ветки слитые с текущей:

git branch --merged

Ветки не слитые с текущей:

git branch --no-merged

git checkout (смена веток)

Перейдем в существующую ветку:

git checkout [branch_existing]

git checkout -b (смена + создание веток)

Создадим и сразу перейдем в нее:

git checkout [new_branch]

Создадим ветку test, взяв за основу удаленную ветку master:

git checkout -b test origin/master

Переносим коммиты в другую ветку или Передвигаем (Откатываем) коммиты

Создадим ветку (feature) от текущей:

git branch feature

Теперь нам нужно передвинуть master на то количество коммитов, которое нам необходимо.

git branch --force master 0b335

Команда выше создаст ветку master, последний коммит которой будет указывать на коммит с хэшем 0b335. Флаг --force (или -f) позволяет проигнорировать информацию о том, что такая ветка уже есть (иначе ветка просто не будет 'передвинута'). Но перед этим необходимо перейти в другую ветку:

git checkout new_f
git branch --force master 0b335

Или, пусть master указывает туда же куда и new_f:

git branch -f master new_f

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

git checkout -b master 0b335

Флаг -B применяется в случае, если такая ветка уже есть и в этом случае ветка будет передвинута:

git checkout -B master 0b335

git merge

Чтобы объединить ветки, например, ветку hotfix с веткой master, необходимо выполнить следующие команды:

git checkout master
git merge hotfix

Объединяем текущую локальную ветку с удаленной:

git merge origin/master

Создаем новую ветку на основе изменений в другой ветке

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

git checkout -b new_feature

Коммитим изменения. Возвращаемся на старую ветку и вы уже не увидите своих изменений - они останутся на ветке new_feature.

--ours к файлу

Допустим, после merge ветки feature в master в файле index.html появились конфликты, при этом мы уверены, что код на ветке master правильный. Чтобы разрешить конфликты в этом случае нам поможет команда:

git checkout --ours index.html

--theirs к файлу

Если нам нужно взять версию из сливаемой (feature) ветки:

git checkout --theirs index.html

--merge к файлу

Вернуться к версии с маркерами конфликта:

git checkout --merge index.html

Отменяем слияние и сбрасываем конфликты

git reset --hard
остановился

reflog

Восстановить удаленную ветку, и не только, нам поможет reflog. Каждый раз, когда мы переключаем ветки, делаем коммиты, да и вообще любой операции, которые меняют ссылки (когда меняется HEAD), Git записывает эти изменения в специальный файл reflog (reference log/ лог ссылок).

Эти файлы находятся в папке ./git/logs.

reflog для ссылки HEAD находится в файле ./git/logs/HEAD

При каждом изменении коммита, на который указывает HEAD в файл ./git/logs/HEAD добавляется новая строка

Для адекватного вывода reflog используют команду, например, для ветки master:

git reflog master

Или без аргументов выведет reflog для HEAD:

git reflog

Что аналогично:

git reflog show

Зачем нужен reflog:

1. Если мы удалили ветку fix неделю назад и уже не помним какие идентификаторы (ХЭШИ) там были, но нам понадобились какие-то коммиты из ветки fix. При этом обычная команда git log не покажет нам эти коммиты. Но так как HEAD когда-то стоял на этих коммитах, то по reflog мы можем их найти. Например, по описанию коммита в reflog: 'fix was here'. Также можно ориентировать по последнему checkout: moving from fix to master.

Восстановим ветку по коммиту (под windows потребуются ''):

git branch feature 'HEAD@{6}'

Выводим reflog с датой:

git reflog --date=iso

2. Переходим на предыдущую ветку, с которой был checkout на текущую ветку:

git checkout @{-1}

Как работает: по reflog ищет ближайший checkout на текущую ветку.

Теги

Кроме веток есть еще оди вид ссылок на коммиты - теги.

git stash (сохраняем изменения)

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

Для таких случае существует команда stash. Команда stash собирает незакоммиченные изменения, удаляет их из файлов и в специальном виде архивирует в Git.

git stash

git stash pop

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

git stash pop

Ошибки при git stash

Иногда мы можем сделать git stash pop не на той ветке, где сохранили изменения, это может привести к ошибке.

Просмотр истории и старых версий

git log

Для просмотра изменений (истории коммитов) используется команда

git log

, которая покажет список последних коммитов и их хеши SHA1. Первыми показываются последние коммиты.

Или можно использовать

git log --oneline

Или для конкретной ветки

git log master --oneline

У git log множество возможностей, например, мы можем выводить историю в более удобном формате:

git log --pretty=format:"%h - %an, %ar : %s"
  • %h – короткий код самого коммита;
  • %an – автор;
  • %ar – когда был сделан;
  • %s - комментарий;
  • %H - Хеш-код коммита;

Ограничивать коммиты по времени:

git log --since=2.weeks

Показывать разницу, внесенную каждым коммитом:

git log -p -2
  • -p показывает разницу, внесенную каждым коммитом. -2 ограничивает выводимый результат последними 2 записями.
  • --stat используется для получения краткой статистики по каждому коммиту.
  • --graph добавляет графику с историей ветвлений и слияний

git log ..

git log name_branch..origin/master

name_branch..origin/master сужит фильтром для команды log и означает, что отображать следует только те коммиты из origin/master, которых нет в name_branch.

git log - выводим нужные коммиты

Зададим какие именно коммиты нужно выводить. git log по умолчанию выводит коммиты достижимые из HEAD. Но можно задать коммиты, например, по хэшу, ветке, и тогда будет выведены коммиты достижимые по хэшу, ветке.

git log master
git log 34assd

Из двух веток:

git log master feature --graph

Выведем коммиты достижимые из всех ссылок:

git log --all --graph

Просмотр коммитов (кроме)

Например, нам нужно просмотреть коммиты, которые произошли в ветке feature, которые, в свою очередь, произошли с момента ее расхождения от master (то есть КРОМЕ коммитов на ветке master):

git log feature ^master

аналогично:

git log master..feature

Просмотр коммитов (И различий) по файлу

Выведем коммиты, в которых менялся файл index.html:

git log index.html

Выведем конкретные различия, в которых менялся файл index.html:

git log -p index.html

Флаги-фильтры для log (поиск изменений в файлах)

Флаги-фильтры - позволяют искать коммиты по их свойствам.

   Флаг-фильтр --grep

Поиск всех коммитов в описании которых есть слово word:

git log --grep word

сделаем регистронезависимым:

git log --grep word -i

   Флаг-фильтр -G

Поиск по изменениям, например, была функция doAny() - нам нужно найти, что было с ней ранее. С флагом -G git выведет все коммиты, в изменениях которых есть строка, которая подпадает под регулярное выражение doAny().

Найдем вызов функции:

git log -GdoAny() -p

Найдем объявление функции:

git log -G'function doAny\(' -p

Не забывайте, что function doAny\( это регулярное выражение.

Флаг -p позволяет увидеть непосредственно изменения.

   Флаг-фильтр -L

Выводи все коммиты с n-й по n-ю строку, например, выведем с 3-й по 7-ю строку:

git log -L 3,7:index.html

Или найдем фрагмент кода по регулярному выражению:

git log -L '/<head>/','/<\/head>/':index.html

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

git show

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

git show e740

текущий коммит (флаг --pretty=fuller позволяет вывести всю информацию):

git show --pretty=fuller

git show (Смотрим на коммит родителя/предыдущий)

git show HEAD~

~~ смотрит на 2 коммита вниз (~~~ на три и т.д.):

git show HEAD~

Тоже самое можно указать через число:

git show HEAD~1
git show HEAD~2
git show HEAD~3

Как посмотреть на файл в предыдущем коммите

Флаг HEAD можно заменить @:

git show @~:index.html

Посмотрим на файл index.html в ветке master:

git show master:index.html

Смотрим на текущую (проиндексированную) версию файла

git show :index.html

Ищем коммит по описанию (слову)

git show :/text

Ветка неважна.

Кто написал эту строку? git blame

Вывести информацию о том, кто написал каждую строку в package.json:

git blame  package.json

Сократим дату и выведем только те строки, которые нас интересуют (например, с 5-й по 8-ю):

git blame  package.json --date=short -L 5,8

git reset

Иногда нежелательные коммиты попадают в репозиторий. Чтобы отменить такие коммиты используют команду reset, где 1ea3e это коммит, на который мы хотим вернуться:

git reset 1ea3e

Или на один коммит назад (@ - HEAD, ~ - родительский коммит):

git reset @~

Флаг --hard с reset

--hard - жесткий reset: передвигает ветку на указанный коммит и обновляет рабочую директорию с индексом на момент указанного коммита (1ea3e).

git reset --hard 1ea3e

Как вернуть коммит, убранный reset

Что если нам потребуется вернуть коммит, который был удален командой reset. Для этого находим коммит по reflog (см. описание к reflog):

git reflog master
git branch feature 'HEAD@{6}'

Или когда мы перемещаем ветку при помощи команды reset, то Git записывает предыдущее значение HEAD в файл ./git/ORIG_HEAD и мы можем использовать его в качестве ссылки:

git reset --hard ORIG_HEAD

Флаг --soft с reset

--soft - мягкий reset: передвигает ветку на указанный коммит, но в отличие от жесткого reset, рабочую директорию с индексом не затрагивает. Так как рабочая директория и индекс не затронуты, то в них останутся версии файлов от коммита, с которого мы ушли (могут появиться файлы 'Changes to be commited').

Подведем итог: мягкий reset отменяет коммит, но оставляет все подготовленные для коммита данные.

git reset --soft @~

Флаг --mixed (по умолчанию) с reset

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

git reset @~
git reset HEAD

или

git reset

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

Статья на хабре про reset: 3 режима команды git reset: --soft, --mixed(по умолчанию), --hard

-----------остановился (для reset)-----------

Флаг --amend

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

git add .

Для замены коммита запускаем:

git commit --amend

Команда git commit --amend сделала следующие два действия:

git reset --soft @~
git reset -c ORIG_HEAD

Конфликты в Git

Команда git status позволяет увидеть файлы с конфликтами.

<<<<<<< HEAD
// Fry comment
=========
// Bender comment
>>>>>>> 1ea3ease3232323easasea6sase6as5eas6aseas4e

Обратите внимание. Изменения в файлах из ветки с указателем HEAD (текущая ветка) располагаются над =========, соответственно в нижней части изменения из ветки, которая входит в текущую.

cherry-pick

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

Например, поместим коммит 268510c2f в ветку master (текущая).

git cherry-pick  268510c2fca7cda7f8efc8bf38727fce3e543438

rebase

Команда rebase своего рода швейцарский нож для истории в git - с ее помощью можно переписывать историю - объединять, редактировать, менять местами коммиты. Но самое главное применение - это перенос или перебазирование веток.

Перенос веток

Допустим, у нас есть две ветки feature и master; ветка master ушла вперед и нам нужно перенести коммиты из master в ветку feature, для этого мы можем сделать:

    git rebase master

И ветка feature будет начинаться с более нового состояния master. См. скрин rebase_01

Как это работает: все коммиты из ветки feature (также как это делает cherry-pick) переносятся в ветку master.

При переносе веток возможны конфликты, в этом случае перенос (rebase) будет остановлен на том коммите, в котором возник конфликт - поправьте конфликт (зафиксируйте изменения) и выполните команду:

    git rebase --continue

Отказ от переноса

Чтобы отказаться от переноса (например, ваш rebase остановился на конфликте) выполните команду:

    git rebase --abort

Чтобы пропустить коммит при переносе, например, rebase остановился на конфликте, вы можете выполнить команду:

    git rebase --skip

Отмена rebase

Отмена rebase после того как rebase завершился.

    git reset --hard ORIG_HEAD

Или (что более надежно).

    git reflog feature

Работаем с bitbucket.org

1. кликаем по this repository Fork

2. клонируем

3. создадим ветку (на основе удаленной ветки test-git)

4. и внесем в нее какие-либо изменения

5. Фиксация изменений

6. Отправка новой ветки в ветку на bitbucket

git push origin test-git-fork

Далее переходи на bitbucket

7. Находим нужную ветку и делаем Create pull request (запрос на включение): где вы можете выбрать как проекты, так и ветки куда пойдет запрос на слияние.

Владелец проекта может выделить часть кода и написать к нему комментарий. Как только это произойдет пользователь, открывший запрос на включение получит уведомление. Пользователь вносит правки и отправляет его.

 

8. Принимаем pull request

 

Полезные приемы

Как в git заменить ветку master полностью другой веткой?

Я имею две ветки в моем репо:

1. master

2. seotweaks (создана от master)

Ветка seotweaks ушла далеко вперед относительно ветки master. Как заменить весь контент ветки master на контент из ветки seotweaks?

Конечно, можно удалить все из ветки master, а затем сделать merge, но это не совсем верная практика.

Ответ:

Вы можете использовать “ours” стратегию при merge, чтобы перезаписать master на seotweaks, например:

git checkout seotweaks
git merge -s ours master
git checkout master
git merge seotweaks

Как результат ветка master по существу станет seotweaks.

(-s ours алиас для --strategy=ours)

Документация по “ours” стратегии

Источник

И наоборот:

git merge -X theirs branchB

Как откатить локальную ветку до состояния удаленной ветки

git reset --hard origin/master
Добавить комментарий