Как стать автором
Обновить

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

Уровень сложностиПростой
Время на прочтение5 мин
Количество просмотров32K
Всего голосов 60: ↑58 и ↓2+71
Комментарии38

Комментарии 38

Спсибо, полезно. Большинство разработчиков вообще нажимают в консоле: вверх, а затем enter. А у них там такой код: git add . && git commit -am "dev" && git pull origin master && git push origin master :)

Поинтересуюсь: а есть какая-то причина использовать аргумент -a в commit, разве git add . перед этим не делает то же самое?

Да есть. Ключ -a это all, который добавляет все изменения в коммит, в том числе, которые сделаны командами add и rm, удаленные файлы. А ключ -m это message, сообщение.

"commit -a" добавит в коммит измененные файлы, которые ранее уже были добавлены через add
"commit add" - добавит в коммит файлы, которые ранее не были добавлены. Причем он может добавить даже файлы, которые сейчас игнорируются через .gitignore
Поэтому тут нужно думать что делать

Блин, не пользовался консольным гитом уже тыщу лет, может больше.

А чем пользуетесь?

Я после перехода с WebStorm на VS Code так и не нашел такого же крутого UI как был у JetBrains. По крайней мере в бесплатных программах. Остановился на Git Extensions, но не дотягивает он. Часто становится проще в консоли что-то сделать, чем через него

Git Ex) мне для своих нужд - хватает

Уже лет 10 не могу представить свою разработку без SmartGit. Пробовал другие клиенты, но SmartGit для меня удобнее всего.

Добавлю, что именно со SmartGit, работа с сабмодулями - раскрывается на полную!

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

А для меня сильной стороной является аналог интерактивного добавления (git add -i), когда прямо в окне diff раскидываю, какие блоки или строки изменения я стэйджу, какие отменяю, а какие пропускаю до следующего коммита. Прям сказка.

В vscode из коробки такое есть, не помню даже насколько давно, как будто сразу было.

пользовался SmartGit много-много лет, но перешел потом на SourceTree (который ненавижу), потому что дерево строит красивее, но в сабмодули совершенно не умеет, а потом на Fork. Он и в сабмодули умеет, и stash and reapply, и красивые деревья рисует

С SourceTree как раз начинал знакомство с Git UI.

Из красивых - мне понравился GitKraken, там прям все анимированное, все таскается - сделали круто. Но все же остался на SmartGit в угоду его функционалу.

Fork, помню, пробовал как-то пару лет назад, надо будет ещё раз потыкать.

Lazygit. Искал что-то без привязки к платформе/ide. Попривыкал к хоткеям и очень доволен

Хм, это что-то типа консольного UI ?

Попробуйте Sublime Merge, это лучший UI по итогу моих изысканий

Я пользуюсь и PhpStorm и VSCode, но UI мне не удобен. Мне проще и удобнее через консоль чето сделать. Максимум это могу иногда посмотреть, что удобно, кто какую часть файла менял и когда

worktree, честно говоря, выглядит костылём. У нас и так же уже есть концепция параллельно ведущихся изменений - сами ветки. А теперь поверх них громоздят ещё одну концепцию параллельных изменений.

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

И приходится либо делать временный WIP коммит, либо класть изменения на полку (stash), все эти способы требуют доп. телодвижений, имеют свои недостатки.

А разрабы городят ещё костыль, тоже требующий телодвижений и усложняющий процесс разработки.

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

Не знаю как бы работал без Worktree.

Самая крутая фишка в Гите, позволяющая параллельно работать на разных ветках. При этом не имея проблем с их переключением.

Работаешь с фичей - смержил в мастер, тут же проверил в новом окне. В третьем окне - обновил библиотеку в проекте. И все это параллельно без потребности в checkout.

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

Безусловно все зависит от принятого в команде flow, но обычно любые изменения в коде делаются в отдельных ветках, чтобы пройти кодревью и аппрув от команды. Ситуация, когда мы одновременно работаем в 2 ветках, скорее редкость, чем правило. Но даже в такой ситуации нет сложности сделать коммит изменений, переключиться в новую ветку и вести там работу. В принципе worktree аналогичен тому, чтобы самому сделать чекаут проекта в 2 разных каталога и работать "параллельно".

Нет, не аналогичен)

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

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

У нас он используется - вообще как основной инструмент Гита, так как несколько игр основаны на одном репозитории, но в разных ветках с использованием сабмодулей. При этом есть базовая ветка для общих изменений (привет структуре Unity). И как раз таки именно Worktree - очень упростил работу, что бы не клонировать отдельные репозитории и не таскать туда сюда (push/pull) изменения.

Абслютно согласен. Где бы ни работал и какой бы процесс ни был (тот же gitflow), git worktree неимоверно облегчает процесс:

  • пошарить экран с какой-то ветки на созвоне и не трогать текущую (не делать временных коммитов и прочих телодвижений, про которые писал lightman);

  • посмотреть ПР и стащить себе ветку в worktree, не трогая предыдущие 2 ветки;

  • держать ветки с разными релизами актуальными, чтобы не делать clean build каждый раз, когда меняешь ветки;

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

Если еще и виме работаешь, то открыть другую папку с проектом — дело 100мс. С IntellijIdea тут может быть немного неудобно: проект может долго открываться и индексироватсья, обновлять gradle и пр.

В условиях, когда все пользуются GUI для git'а, bisect выглядит анахронизмом.

Все это кто?

А я кого не спрашивал, либо пользуются консолью, либо "черепашкой" коммитят все изменения разом.
Ну а bisect так же неплохо работает и через GUI в том же `SmartGit`.

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

bisect'у можно скормить скрипт для проверки «этот коммит хороший?» и уйти пить чай, а потом прийти и увидеть тот самый коммит-проблему. При условии что не будет false-negative кейсов, как например если мы просто пробуем делать make, а у нас есть коммиты откровенно хламовые.

Про разницу команд git switch и git checkout:

1. Переключение веток с сохранением локальных изменений:   

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

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

(Именно здесь и только здесь есть единственная разница в проверках, никаких extra sanity checks вgit switch не происходит, есть только различие в поведении на основе этих проверок, а значит статья содержит неточность)

2. Копирование файлов из другой ветки в рабочее дерево:

 - git checkout <branch> -- <file> позволяет скопировать файл из указанной ветки непосредственно в рабочее дерево без переключения веток.

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

3. Переключение на предыдущую использованную ветку:

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

   - git checkout <previous-branch> требует ввода названия ветки

4. У команды   git switch не убран статус "экспериментальная", её поведение ещё может измениться. Встраивать в свой конвеер без заморозки версии git не рекомендуется.

Список основных различий исчерпывающий, остальные мелкие различия это нюансы семантики.

Статья содержит ошибку "the new git switch only switches the branch" - переход на коммит возможен командой git switch --detach <commit>, при котором также как и при команде git checkout <commit> производится открепление HEAD от ветки, поэтому это аналогичные команды. Эта ошибка есть почти во всех статьях про разницу этих команд, возможна связана с изменением поведения команды, а может является мифом.

При составлении ответа использованы: 

1. perplexity,

2. официальная документация (https://git-scm.com/docs/git-switch , https://git-scm.com/docs/git-checkout )

3. chatpdf (  бесплатные 20 вопросов)

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

ваш коммент полезнее статьи, и сам по себе ближе к статье нежели к комменту

Спасибо) Если это рекомендуемый уровень информационной насыщенности для статьи Хабра, могу опубликовать в виде статьи. Подготовка коммента заняла где-то полтора часа.

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

git checkout - прекрасно работает, такой синтаксис есть еще в, например, bash: cd - вернуться в предыдущую папку

кажется пора что-то попроще поискать..

может fossil попробовать

git и так максимально простой.
Его особенность - высокая гибкость. Хочешь - юзай rebase, хочешь - юзай cherry-pick, хочешь - юзай сабмодули.
Или просто git pull, git commit, git push

если вы пользуетесь как раз теми 5 командами, о которых написал автор.
А теперь введите git<tab><tab> и увидите еще с десяток о которых вы не слышали. И у каждой еще по десять опций)

В гите целая куча неочевидностей. Возьмите хоть те же checkout/switch)

[тут](https://habr.com/p/353654/) есть немного аргументации и ссылки по теме

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

Вопрос в том - зачем использовать что-то "попроще", если в гите не обязательно что-либо усложнять, и можно пользоваться только простыми командами.
Я прям даже не могу сказать, что пригодится нетребовательному юзеру в гите из нестандартных pull, commit, push.
Ну может разово "git update-index --chmod=+x install.sh"

git отлично работает по дефолту, при этом УЖЕ интегрирован и готов к работе в связке с подавляющим большинством современных инструментов (ide, ci/cd и так далее).

может мной просто движет желаете найти что-то получше)

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

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

Можно попробовать посмотреть на меркуриалы/базары, или sourcesafe/svn... Но похоже они не выдержали конкуренцию, хотя по внутренней работе были моменты где в определенный момент были лучше

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории