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

1. Слияние против перебазирования

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

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

Всего у нас две ветки - основная и функциональная. Основа функциональной ветки - это фиксация «ab».

Объединить

Если разработка функциональной ветки завершена, и мы хотим переместить изменения в основную ветку, мы используем команду merge.

git checkout master
git merge feature

Путем слияния функции с мастером мастер получает новую фиксацию - в нашем примере предположим, что это «xyz».

Новая фиксация xyz добавляется в главное дерево ветки, которое представляет каждое изменение, произошедшее в ветке функции. Здесь основой функциональной ветки по-прежнему является фиксация «ab».

Rebase

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

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

git checkout feature
git rebase master

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

Теперь основание функциональной ветви изменено с «ab» на «abcd». Из приведенного выше дерева видно, почему в этой ситуации мы выбираем перебазирование вместо слияния. В отличие от слияния, rebase не создает дополнительной фиксации. Это идеально для нашей ситуации, поскольку все, что мы сейчас пытаемся сделать, - это поддерживать нашу функциональную ветку в актуальном состоянии с учетом любых новых коммитов от мастера. Основным преимуществом перебазирования является то, что мы получаем намного более чистое дерево коммитов.

Различия между перебазированием и слиянием:

  • В результате древовидная структура истории отличается. (обычно это заметно только при просмотре графика фиксации)
  • Слияние обычно создает дополнительную фиксацию.
  • Слияние и перебазирование будут обрабатывать конфликты по-разному. Rebase будет представлять конфликты одного коммита за раз, а слияние представит их все сразу.

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

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

2. Разрешение конфликтов после перезагрузки Git

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

error: could not apply ba66749... something to add to patch A
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Could not apply ba66749b807321c786a65bbb9b2169b7a6ed957d... Change fake file

У нас есть три варианта исправить коммит, вызывающий конфликт (ba66749):

  • git rebase --abort: чтобы полностью отменить перебазирование. Это отмотает все изменения перебазирования и вернет ветку в состояние, в котором она была до вызова git rebase.
  • git rebase --skip: полностью пропустить фиксацию. Следовательно, ни одно из изменений, внесенных фиксацией (ba66749), не будет включено в историю.
  • Мы можем исправить конфликт, используя стандартную процедуру разрешения конфликтов слияния.

3. Временно храните изменения.

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

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

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

$ git stash

При использовании команды git stash все неотслеживаемые файлы сохраняются. Но что, если мы хотим спрятать один указанный файл. Вот как мы можем это сделать:

$ git stash push <path>

4. Удалить фиксацию - локально и удаленно.

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

Если изменения еще не были внесены, и мы хотим удалить последнюю фиксацию, вот способ сделать это

# Use --soft if you want to keep your changes
git reset --soft HEAD~1
# Use --hard if you don't care about keeping the changes you made
git reset --hard HEAD~1

В некоторых случаях мы хотим удалить фиксацию, но сохранить наши изменения для небольшого редактирования, прежде чем мы сделаем лучшую фиксацию. Команда--soft сохранит все изменения рабочего дерева, а команда--hard отменит все изменения рабочего дерева. Приведенные выше команды перемещают HEAD в коммит перед HEAD. Если мы хотим удалить коммиты до определенной фиксации, запустите git log в командной строке, чтобы найти конкретный идентификатор фиксации, а затем выполните команду ниже.

# Use --soft if you want to keep your changes
git reset --soft <commit-id>
# Use --hard if you don't care about keeping the changes you made
git reset --hard <commit-id>

Это переместит HEAD в коммит.

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

git push origin +<branch-name>

Знак + перед названием ветки указывает git принудительно выполнить push.

Мы можем удалить последний n коммит с помощью следующей команды

# Delete last two commits
git reset --hard HEAD~2
# Delete last n commits
git reset --hard HEAD~n

5. Вишневый сбор

Когда мы работаем с командой разработчиков над средним и крупным проектом, управление изменениями между несколькими ветвями git может стать сложной задачей. Иногда мы не хотим объединять целую ветку с другой, и нам нужно выбрать только один или два конкретных коммита. Чтобы выполнить эту операцию, мы можем использовать команду cherry-pick. Он принимает изменения из определенного коммита и применяет их к вашей текущей ветке в новом коммите.

git cherry-pick <commit-id>

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

a - b - c - d        Master
         \
           e - f - g Feature

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

git cherry-pick f

После выполнения наша история Git будет выглядеть так:

a - b - c - d - f    Master
         \
           e - f - g Feature

Фиксация f была успешно добавлена ​​в главную ветку.

6. Очистить - удалить все неотслеживаемые изменения.

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

# list all files that would be removed
git clean -n
# list all files/directories that would be removed
git clean -n -d

Результат будет выглядеть примерно так:

# Output of git clean -n command
Would remove project/blog/example.txt
# Output of git clean -n -d command
Would remove project/test/
Would remove project/blog/example.txt

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

git clean -d -f

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

Параметр -f означает силу.

В итоге,

git clean -f     # remove untracked files
git clean -d -f  # remove untracked files/directories

7. Кто все это сделал?

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

git blame <fileName>

Например, мы хотим изучить файл manage.py.

git blame manage.py
Output

66fe3ebef (Tony  2020-06-14 11:33:01 +0530  1) import os;
3e537ffda (steve 2020-05-29 18:45:17 +0530  2) import sys;
5c5490232 (Tony  2020-06-14 09:55:03 +0530  3) import requests;

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