CS Visualized: полезные команды Git
Перевод статьи Lydia Hallie — CS Visualized: Useful Git Commands
Хотя Git является очень мощным инструментом, я думаю, что большинство людей согласятся, когда я скажу, что он также может быть … полным кошмаром 😐 Мне всегда было очень полезно визуализировать в своей голове, что происходит при работе с Git: как ветви, взаимодействуют, когда я выполняю определенную команду, и как это повлияет на историю в git? И почему мой коллега заплакал, когда я сделал полный reset на master, выполнив принудительный push к origin и переименовав в rimraf папку .git?
Я подумал, что эта статья будет идеальным вариантом для создания наглядных примеров наиболее распространенных и полезных команд! 🥳 Многие из описываемых мной команд имеют необязательные аргументы, которые вы можете использовать для изменения их поведения. В моих примерах я расскажу о поведении команд по умолчанию, не добавляя (слишком много) параметров конфигурации! 😄
Merging
Наличие нескольких веток чрезвычайно удобно для того, чтобы новые изменения были отделены друг от друга, а также чтобы вы случайно не отправили несанкционированные или не корректные изменения в производство. Как только изменения будут одобрены, они могут быть слиты с нашей производственной версии!
Один из способов получить изменения из одной ветви в другую — выполнить git merge имя коммита! Есть два типа слияний, которые может выполнять Git: fast-forward или no-fast-forward 🐢
Давайте посмотрим на различия!
Fast-forward (--ff
)
fast-forward merge можно использовать, когда текущая ветвь не имеет дополнительных коммитов по сравнению с веткой, с которой мы объединяемся. Git … ленив и сначала попытается выполнить самый простой вариант: fast-forward! Этот тип слияния не создает новый коммит, а скорее объединяет коммит (ы) в ветви, которую мы объединяем прямо в текущей ветви 🥳
Отлично! Теперь у нас есть все изменения в ветке master, которые были сделаны в ветке dev . Итак, что же такое no-fast-forward?
No-fast-foward (--no-ff
)
Хорошо, если ваша текущая ветвь не имеет каких-либо дополнительных коммитов по сравнению с веткой, с которой вы хотите объединиться, но, к сожалению, это случается редко! Если мы закоммители изменения в текущей ветви, которых нет в ветви, с которой мы хотим объединиться, git выполнит объединение без no-fast-forward.
При no-fast-forward merge Git создает новый merging commit в активной ветви. Родительский коммит указывает на активную ветвь и ветвь, которую мы хотим объединить!
Теперь у нас новый коммит 9e78i 🎉Ветка master теперь содержит все изменения, которые мы внесли в ветку dev.
Merge Conflicts
Хотя Git хорошо решает, как объединять ветви и добавлять изменения в файлы, он не всегда может самостоятельно принять это решение. 🙂 Это может произойти, когда две ветви, которые мы пытаемся объединить, имеют изменения в одной строке в одном файле, или если одна ветка удалила файл, который изменила другая ветка, и так далее.
В этом случае Git попросит вас помочь решить, какой из двух вариантов мы хотим сохранить! Допустим, что в обеих ветках мы отредактировали первую строку в файле README.md.
Если мы хотим объединить dev с master, это приведет к конфликту слияния: какой заголовок должен быть оставлен Hello! или Hey!?
При попытке объединить ветви, Git покажет вам, где произошел конфликт. Мы можем вручную: удалить изменения, которые не хотим сохранять, сохранить изменения, снова добавить измененный файл и зафиксировать изменения 🥳
Хотя конфликты слияний часто довольно раздражают, они определенно нужны: Git просто должен предполагать, какие изменения мы хотим сохранить.
Rebasing
Мы только что увидели, как можно применить изменения из одной ветви в другую, выполнив git merge. Другой способ добавить изменения из одной ветви в другую — выполнить git rebase.
git rebase копирует коммиты из текущей ветви и помещает эти скопированные коммиты поверх указанной ветви.
Теперь все изменения, которые были сделаны в основной ветке master, добавлены в ветку dev! 🎊
Основная разница по сравнению с merging заключается в том, что Git не будет пытаться выяснить, какие файлы сохранить и не сохранить. В ветке, которую мы обновляем, всегда есть последние изменения, которые мы хотим сохранить! Таким образом, вы не столкнетесь ни с какими конфликтами слияния, и у вас будет хорошая линейная история Git. (То есть, в этом случае всегда используются только последние изменения)
Этот пример показывает rebasing в основной ветке master. Однако в больших проектах вы обычно не хотите этого делать. git rebase изменяет историю проекта, поскольку для скопированных коммитов создаются новые хэши!
Rebasing отлично подходит, когда вы работаете над вашей веткой, а основная ветвь была обновлена. Вы можете получить все обновления в свою ветку, которые предотвратят будущие конфликты слияний! 😄
Interactive Rebase
Перед rebasing коммитов мы можем их изменить! 😃 Мы можем сделать это с помощью interactive rebase. Interactive rebase также может быть полезен для ветки, над которой вы сейчас работаете, и хотите изменить некоторые коммиты.
Есть 6 действий, которые мы можем выполнить над коммитами, которые мы rebasing:
reword
: Изменить commit сообщенияedit
: Изменить этот коммитsquash
: Объединить коммит с предыдущий коммитомfixup
: Объединить коммит с предыдущим коммитом, не сохраняя сообщения журнала коммитаexec
: Запустите команду для каждого коммита, который мы хотим rebasedrop
: Удалить коммит
Таким образом, мы можем получить полный контроль над нашими коммитами. Если мы хотим удалить коммит, мы можем просто drop его.
Или, если мы хотим объединить несколько коммитов вместе, чтобы получить более чистую историю, нет проблем!
Interactive rebasing дает вам большой контроль над коммитами, которые вы пытаетесь rebase, даже в текущей активной ветке!
Resetting
Может случиться так, что мы допустили изменения, которые мы не хотели позже. Может быть, это коммит WIP или коммит, в котором есть ошибки! 🐛 В этом случае мы можем выполнить git reset.
git reset избавляет от всех текущих промежуточных файлов и дает нам контроль над тем, куда должен указывать HEAD.
Soft reset
soft reset перемещает HEAD к указанному коммиту (или индексу коммита по сравнению с HEAD), не избавляясь от изменений, которые были внесены в коммиты позже!
Допустим, мы не хотим сохранять коммит 9e78i, в который был добавлен файл style.css, и мы также не хотим сохранять коммит 035cc, в который был добавлен файл index.js. Однако мы хотим сохранить недавно добавленные файлы style.css и index.js! Идеальный вариант использования для этого soft reset.
Набрав git status, вы увидите, что у нас все еще есть доступ ко всем изменениям, которые были сделаны во время предыдущих коммитов. Это здорово, так как это означает, что мы можем исправить содержимое этих файлов и зафиксировать их позже!
Hard reset
Иногда мы не хотим сохранять изменения, внесенные некоторыми коммитами. В отличие от soft reset, нам не нужно больше иметь к ним доступ. Git должен просто сбросить свое состояние обратно туда, где он был в указанном коммите: это даже включает изменения в вашем рабочем каталоге и промежуточных файлах! 💣
Git отменил изменения, которые были внесены в 9e78i и 035cc, и сбросил свое состояние до того, где он был при commit ec5be.
Reverting
Другой способ отменить изменения — выполнить git revert. Отменяя определенный коммит, мы создаем новый коммит, который содержит отмененные изменения!
Допустим, в ec5be добавили файл index.js. Позже мы на самом деле понимаем, что больше он не нужен, и мы не хотим чтобы это изменение было внесено этим коммитом! Давайте вернем коммит ec5be.
Отлично! Коммит 9e78i отменил изменения, внесенные коммитом ec5be. Выполнение git revert очень полезно для того, чтобы отменить определенный коммит, не изменяя историю ветки.
Cherry-picking
Что бы получить из определенной ветки изменения, которые нам нужны в нашей активной ветке, мы можем использовать команду cherry-pick! Выбирая коммит cherry-pick, мы создаем новый коммит в нашей активной ветке, который содержит изменения, внесенные коммитом cherry-pick.
Предположим, что коммит 76d12 в ветке dev добавила изменение в файл index.js, и нам нужно получить их в нашей основной ветке master.
Круто, ветка master теперь содержит изменения, которые внес 76d12!
Fetching
Если у нас есть удаленная ветка Git, например ветка на Github, может случиться так, что удаленная ветвь имеет коммиты, которых нет в вашей текущей ветки!
Мы можем получить эти изменения локально, выполнив git fetch в удаленной ветке! И это никак не повлияет на вашу локальную ветку: fetch просто загружает новые данные.
Теперь мы можем видеть все изменения, которые были сделаны с момента последнего пуша! Мы можем решить, что мы хотим сделать с новыми данными теперь, когда они у нас есть локально.
Pulling
Хотя git fetch очень полезен для получения удаленной информации о ветке, мы также можем выполнить git pull. git pull — это две команды в одной: git fetch и git merge. Когда мы извлекаем изменения из источника, мы сначала извлекаем все данные, как мы делали с помощью git fetch, после чего последние изменения автоматически объединяются в локальную ветвь.
Круто, теперь мы отлично синхронизированы с удаленной веткой и имеем все последние изменения! 🤩
Reflog
Все делают ошибки, и это совершенно нормально! Иногда может показаться, что вы испортили свой репозиторий Git настолько сильно, что просто хотите полностью его удалить.
git reflog — очень полезная команда для отображения журнала всех выполненных действий! Это включает в себя merges, resets, reverts: в основном, любые изменения в вашей ветке.
Если вы допустили ошибку, вы можете легко исправить ее, сбросив HEAD на основе информации, которую нам предоставляет reflog!
Скажем, мы на самом деле не хотели объединять ветку source. Когда мы выполняем команду git reflog, мы видим, что состояние репо до слияния — HEAD@{1}. Давайте выполним git reset, чтобы указать HEAD туда, где он был на HEAD@{1}!
Мы видим, что последнее действие было перенесено в reflog!
У Git так много полезных команд, что я не могу их всех охватить в этой небольшой статье! Я знаю, что есть много других команд, которые я не успел осветить прямо сейчас — дайте мне знать, какие ваши любимые / самые полезные команды, и я расскажу о них в другом посте!
И как всегда, не стесняйтесь обращаться ко мне! 😊 (Оригинальная статья https://dev.to/lydiahallie/cs-visualized-useful-git-commands-37p1)
Спасибо за полезную статью, как раз хотела изучать команды Git.