1. Обзор
Git — довольно популярная на сегодняшний день система контроля версий.
В этом кратком руководстве мы рассмотрим, как переместить существующие, но незафиксированные изменения в новую ветку.
2. Введение в проблему
Прежде всего, давайте подумаем о типичном рабочем процессе добавления новой функции в управляемый Git проект:
- Создайте новую ветвь функций, скажем,
функцию
, а затем переключитесь на эту ветвь . - Реализуйте функцию и зафиксируйте ее в нашем локальном репозитории.
- Отправьте ветку функций в удаленный репозиторий и создайте запрос на включение
- После просмотра другим товарищем по команде новое изменение может быть объединено с
основной
илирелизной
веткой .
Однако иногда мы начинали вносить изменения, но забывали о создании новой функциональной ветки и переключении на нее. В результате мы можем понять, что находимся не в той ветке — например, в ветке master
— когда собираемся зафиксировать наши изменения.
Поэтому нам нужно создать новую ветку функций и переместить незафиксированную работу в новую ветку. Более того, ветку master
не следует изменять.
Пример может быстро объяснить этот сценарий. Допустим, у нас есть репозиторий Git с именем myRepo
:
$ git branch
* master
$ git status
On branch master
nothing to commit, working tree clean
Как видно из приведенного выше вывода, сейчас мы находимся на главной
ветке. Также рабочее дерево чистое.
Далее внесем некоторые изменения:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Readme.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
a-new-file.txt
no changes added to commit (use "git add" and/or "git commit -a")
Как видно из приведенного выше вывода, мы добавили новый файл a-new-file.txt
и изменили содержимое Readme.md
. Теперь мы понимаем, что работа должна быть передана в функциональную ветку, а не в основную
ветку.
Далее давайте посмотрим, как перенести изменения в новую ветку и оставить master
без изменений.
3. Использование команды git checkout
Команда git checkout -b <BranchName>
создаст новую ветку и переключится на нее. Более того, эта команда оставит текущую ветку как есть и перенесет все незафиксированные изменения в новую ветку .
Затем давайте протестируем команду git checkout
в нашем проекте myRepo
:
$ git branch
* master
$ git co -b feature1
Switched to a new branch 'feature1'
$ git status
On branch feature1
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Readme.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
a-new-file.txt
no changes added to commit (use "git add" and/or "git commit -a")
Как показывают приведенные выше команды, мы создали ветку feature1
и переместили все незафиксированные изменения из master
в feature1
. Далее, давайте подготовим и зафиксируем изменения:
$ git add . && git commit -m'implemented feature1'
[feature1 2ffc161] implemented feature1
2 files changed, 2 insertions(+)
create mode 100644 a-new-file.txt
$ git log --abbrev-commit feature1
commit 2ffc161 (HEAD -> feature1)
Author: ...
Date: ...
implemented feature1
commit b009ddf (master)
Author: ...
Date: ...
init commit
Теперь давайте вернемся к ветке master
и проверим, не оставили ли мы ее без изменений:
$ git checkout master
Switched to branch 'master'
$ git status
On branch master
nothing to commit, working tree clean
$ git log --abbrev-commit master
commit b009ddf (HEAD -> master)
Author: ...
Date: ...
init commit
Как видно из вывода, в ветке master
нет локальных изменений . Кроме того, на master
также нет новой фиксации .
4. Использование команды git switch
Как мы знаем, команда проверки
Git похожа на швейцарский армейский нож. Одна и та же команда может выполнять множество различных операций, таких как восстановление файлов рабочего дерева, переключение ветвей, создание ветвей, перемещение головы и т.д. Использование команды checkout
довольно перегружено.
Поэтому Git представил команду git switch
начиная с версии 2.23, чтобы устранить некоторую путаницу из- за перегруженного использования команды checkout .
Как следует из названия, git switch
позволяет нам переключаться между ветвями. Более того, мы можем использовать опцию -C
, чтобы создать новую ветку и переключиться на нее одним выстрелом . Она работает почти так же, как команда git checkout -b
.
Далее давайте проведем тот же тест, что и git checkout -b
в проекте myRepo
:
$ git branch
feature1
* master
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm ...)
(use "git restore ...)
deleted: Readme.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
ReadmeNew.md
...
Как видно из приведенного выше вывода, сейчас мы находимся в основной
ветке. На этот раз мы удалили файл Readme.md
и добавили новый файл ReadmeNew.md
.
Далее воспользуемся командой git
switch
, чтобы переместить незафиксированные изменения в новую ветку с именем feature2
:
$ git switch -C feature2
Switched to a new branch 'feature2'
$ git status
On branch feature2
Changes not staged for commit:
(use "git add/rm ...)
(use "git restore ...)
deleted: Readme.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
ReadmeNew.md
...
$ git add . && git commit -m 'feature2 is done'
[feature2 6cd5933] feature2 is done
1 file changed, 0 insertions(+), 0 deletions(-)
rename Readme.md => ReadmeNew.md (100%)
$ git log --abbrev-commit feature2
commit 6cd5933 (HEAD -> feature2)
Author: ...
Date: ...
feature2 is done
commit b009ddf (master)
Author: ...
Date: ...
init commit
Как видно из приведенного выше вывода, git
switch -C
создает новую ветку feature2
и возвращает нас к feature2
. Кроме того, все незафиксированные изменения были перемещены из master
в ветку feature2
. Затем мы зафиксировали изменения в ветке feature2
.
Затем вернемся к ветке master
и проверим, не изменена ли она:
$ git switch master
Switched to branch 'master'
$ git status
On branch master
nothing to commit, working tree clean
$ ls -1 Readme.md
Readme.md
$ git log --abbrev-commit master
commit b009ddf (HEAD -> master)
Author: ...
Date: ...
init commit
Как мы видели, в ветке master
все изменения в файлах рабочего дерева, сделанные нами ранее, были восстановлены. Например, удалённый файл Readme.md
вернулся. Более того, команда git log
не показывает новых коммитов на master
.
5. Вывод
В этой статье мы рассмотрели несколько быстрых способов переместить незафиксированные изменения в новую ветку Git. Обе команды довольно просты в использовании:
git checkout -b <NEW_BRANCH>
git переключатель -C <NEW_BRANCH>