Управление ветками Git

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

Почти каждая система контроля версий поддерживает ветки в той или иной форме; ветка представляет собой независимую линию разработки.

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

Ветки Git на самом деле являются указателями на снимки изменений.

Некоторые называют модель ветвления Gitособой фишкой, и именно благодаря ейGitотличается от семейства систем контроля версий.

Создать ветку

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

git checkout -b <branchname>

Например:

git checkout -b feature-xyz

Команда переключения ветки:

git checkout (branchname)

Например:

git checkout main

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

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

Просмотр всех веток:

git branch

Просмотр удалённых веток:

git branch -r

Просмотр всех локальных и удалённых веток:

git branch -a

Слияние ветки

Слияние других веток с текущей веткой:

git merge <branchname>

Например, переключитесь на ветку main и выполните слияние ветки feature-xyz:

git checkout main
git merge feature-xyz

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

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

Откройте файл с конфликтом и разрешите конфликт в соответствии с маркерами.

Отметьте разрешение конфликта как завершённое:

git add <conflict-file>

Зафиксируйте результат слияния:

git commit

Удалить ветку

Удалить локальную ветку:

git branch -d <branchname>

Принудительно удалить неслитую ветку:

git branch -D <branchname>

Удалить удалённую ветку:

git push origin --delete <branchname>

Пример

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

$ mkdir gitdemo
$ cd gitdemo/
$ git init
Initialized empty Git repository...
$ touch README
$ git add README
$ git commit -m '第一次版本提交'
[master (root-commit) 3b58100] 第一次版本提交
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README

Управление ветками Git

Список веток

Основные команды для вывода списка веток:

git branch

Без аргументов,git branchЭта команда выведет список веток в вашем локальном репозитории.

$ git branch
* master

Этот пример означает, что у нас есть одна ветка, называемаяmaster, и эта ветка является текущей.

Когда вы запускаетеgit init, по умолчанию Git создаст для вас веткуmaster.

Если мы хотим создать ветку вручную, выполнитеgit branch (branchname)Вот и всё.

$ git branch testing
$ git branch
* master
  testing

Теперь мы видим, что есть новая веткаtesting。

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

Далее мы продемонстрируем, как переключать ветки. Мы используем git checkout (branch), чтобы переключиться на ветку, которую хотим изменить.

$ ls
README
$ echo 'example.com' > test.txt
$ git add .
$ git commit -m 'add test.txt'
[master 3e92c19] add test.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt
$ ls
README        test.txt
$ git checkout testing
Switched to branch 'testing'
$ ls
README

Когда мы переключаемся на веткуtesting, новый файл test.txt, который мы добавили, был удалён. Переключаемся обратно наmaster, и при переключении веток они появляются снова.

$ git checkout master
Switched to branch 'master'
$ ls
README        test.txt

Мы также можем использовать команду git checkout -b (branchname), чтобы создать новую ветку и сразу переключиться на неё, что позволяет нам работать в этой ветке.

$ git checkout -b newtest
Switched to a new branch 'newtest'
$ git rm test.txt 
rm 'test.txt'
$ ls
README
$ touch example.php
$ git add .
$ git commit -am 'removed test.txt、add example.php'
[newtest c1501a2] removed test.txt、add example.php
 2 files changed, 1 deletion(-)
 create mode 100644 example.php
 delete mode 100644 test.txt
$ ls
README        example.php
$ git checkout master
Switched to branch 'master'
$ ls
README        test.txt

Как видите, мы создали ветку, удалили файл test.txt в той ветке и добавили файл example.php, затем переключились обратно на нашу основную ветку. Удалённый файл test.txt вернулся, а недавно добавленный example.php отсутствует в основной ветке.

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

Удалить ветку

Команда удаления ветки:

git branch -d (branchname)

Например, если мы хотим удалить ветку testing:

$ git branch
* master
  testing
$ git branch -d testing
Deleted branch testing (was 85fc7e7).
$ git branch
* master

Слияние веток

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

git merge
$ git branch
* master
  newtest
$ ls
README        test.txt
$ git merge newtest
Updating 3e92c19..c1501a2
Fast-forward
 example.php | 0
 test.txt   | 1 -
 2 files changed, 1 deletion(-)
 create mode 100644 example.php
 delete mode 100644 test.txt
$ ls
README        example.php

В приведённом выше примере мы слили ветку newtest в главную ветку, и файл test.txt был удалён.

После слияния вы можете удалить ветку:

$ git branch -d newtest
Deleted branch newtest (was c1501a2).

После удаления остаётся только ветка master:

$ git branch
* master

Конфликт слияния

Слияние — это не просто операция добавления или удаления файлов; Git также объединяет изменения.

$ git branch
* master
$ cat example.php

Примечание:Если файл example.php не существует, сначала нужно создать этот файл. Команда может бытьtouch example.php。

Сначала мы создаём ветку с именем change_site, переключаемся на неё и меняем содержимое example.php на:

<?php
echo 'example';
?>

Создайте ветку change_site:

$ git checkout -b change_site
Switched to a new branch 'change_site'
$ vim example.php
$ head -3 example.php
<?php
echo 'example';
?>
$ git commit -am 'changed the example.php'
[change_site 7774248] changed the example.php
 1 file changed, 3 insertions(+)
 

Для работы с командами vim обратитесь к:Linux vi/vim。

Зафиксируйте изменённое содержимое в ветке change_site. Теперь, если мы переключимся обратно на ветку master, мы увидим, что содержимое восстановлено до того, каким оно было до наших изменений (пустой файл, без кода). Мы снова изменяем файл example.php.

$ git checkout master
Switched to branch 'master'
$ cat example.php
$ vim example.php    # 修改内容如下
$ cat example.php
<?php
echo 1;
?>
$ git diff
diff --git a/example.php b/example.php
index e69de29..ac60739 100644
--- a/example.php
+++ b/example.php
@@ -0,0 +1,3 @@
+<?php
+echo 1;
+?>
$ git commit -am '修改代码'
[master c68142b] 修改代码
 1 file changed, 3 insertions(+)

Теперь эти изменения записаны в мою ветку "master". Далее мы выполним слияние ветки "change_site".

$ git merge change_site
Auto-merging example.php
CONFLICT (content): Merge conflict in example.php
Automatic merge failed; fix conflicts and then commit the result.

$ cat example.php     # 打开文件,看到冲突内容
<?php
<<<<<<< HEAD
echo 1;
=======
echo 'example';
>>>>>>> change_site
?>

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

$ vim example.php 
$ cat example.php
<?php
echo 1;
echo 'example';
?>
$ git diff
diff --cc example.php
index ac60739,b63d7d7..0000000
--- a/example.php
+++ b/example.php
@@@ -1,3 -1,3 +1,4 @@@
  <?php
 +echo 1;
+ echo 'example';
  ?>

В Git мы можем использовать git add, чтобы сообщить Git, что конфликт в файле разрешён

$ git status -s
UU example.php
$ git add example.php
$ git status -s
M  example.php
$ git commit
[master 88afe0e] Merge branch 'change_site'

Теперь мы успешно разрешили конфликт слияния и зафиксировали результат.


Руководство по команде

Команда Описание Пример использования
git branch Показать список, создать или удалить ветки. Она не переключает ветки; она используется только для управления существованием веток. git branch: Показать список всех веток
git branch new-branch: Создать новую ветку
git branch -d old-branch: Удалить ветку
git checkout Переключиться на указанную ветку или восстановить файлы в рабочем каталоге. Она также может использоваться для переключения на определённые коммиты. git checkout branch-name: Переключиться на ветку
git checkout file.txt: Восстановить файлы в рабочей области
git checkout <commit-hash>: Переключиться на конкретный коммит
git switch Специально используется для переключения веток, по сравнению сgit checkoutЭто более лаконично и интуитивно понятно, в основном используется для операций с ветками. git switch branch-name: Переключиться на указанную ветку
git switch -c new-branch: Создать и переключиться на новую ветку
git merge Слить изменения из указанной ветки в текущую ветку. git merge branch-name: Слить изменения из указанной ветки в текущую ветку
git mergetool Запустить инструмент слияния для разрешения конфликтов слияния. git mergetool: Использовать инструмент слияния по умолчанию для разрешения конфликтов
git mergetool --tool=<tool-name>: Указать инструмент слияния
git log Показать историю коммитов. git log: Показать историю коммитов
git log --oneline: Отобразить историю коммитов в кратком режиме
git stash Сохранить незакоммиченные изменения в текущем рабочем каталоге и вернуть его в чистое рабочее состояние. git stash: Сохранить текущие изменения
git stash pop: Восстановить последние сохранённые изменения
git stash list: Показать все сохранённые изменения
git tag Создавать, просматривать или удалять теги. Теги используются для отметки определённых коммитов. git tag: Показать все теги
git tag v1.0: Создать новый тег
git tag -d v1.0: Удалить тег
git worktree Позволяет извлекать несколько рабочих пространств из одного репозитория, что подходит для одновременной работы с несколькими ветками. git worktree add <path> branch-name: Добавить новое рабочее пространство по указанному пути и переключиться на указанную ветку
git worktree remove <path>: Удалить рабочий каталог
Другие расширения