Почему git продолжает показывать мои изменения, когда я переключаю ветки (измененные, добавленные, удаленные файлы), независимо от того, запускаю я git add или нет?

115

Я действительно новичок в git, и я пытался понять, почему git продолжает показывать все, что я изменил в одной ветке в другой ветке, когда я запускаю git checkout для переключения между ветвями. Сначала я попытался не использовать git add и не работал. Однако затем я попытался использовать git add, но не устранил проблему. Я пока не использую git commit.

В основном это то, что я делаю:

$ git clone <a_repository>  
$ git branch  
* master  
$ git branch testing  
$ git checkout testing  
...edit a file, add a new one, delete...  
$ git status  
    # On branch testing  
    # Changed but not updated:  
    #   (use "git add/rm <file>..." to update what will be committed)  
    #   (use "git checkout -- <file>..." to discard changes in working directory)  
    #  
    #       deleted:    file1.txt  
    #  
    # Untracked files:  
    #   (use "git add <file>..." to include in what will be committed)  
    #  
    #       file2.txt  
no changes added to commit (use "git add" and/or "git commit -a")  
$ git branch  
  master  
* testing  
$ git checkout master  
D       file1.txt  
Switched to branch 'master'  
$ git status  
    # On branch master  
    # Changed but not updated:  
    #   (use "git add/rm <file>..." to update what will be committed)  
    #   (use "git checkout -- <file>..." to discard changes in working directory)  
    #  
    #       deleted:    file1.txt  
    #  
    # Untracked files:  
    #   (use "git add <file>..." to include in what will be committed)  
    #  
    #       file2.txt  
no changes added to commit (use "git add" and/or "git commit -a")  

Я думал, что при использовании веток все, что вы делаете в одной ветке, невидимо для всех других веток. Разве это не причина создания веток?

Я пробовал использовать "git add", но изменения видны в обеих ветках. Нужно ли мне запускать "git commit" перед переключением между ветвями, чтобы этого избежать?

JPZ
источник

Ответы:

142

Смена ветки несет с собой незафиксированные изменения. Либо сначала зафиксируйте, либо запустите, git checkout .чтобы отменить их, либо запустите git stashдо переключения. (Вы можете вернуть свои изменения с помощью git stash apply)

Шон Кларк Хесс
источник
10
git stash pop лучше, если вы не хотите создавать огромную стопку тайников.
siride
7
@JPZ: git stash работает только с отслеживаемыми файлами; новые файлы не отслеживаются, поэтому они не будут храниться.
siride
2
@JPZ: если вы хотите спрятать неотслеживаемые файлы, лучше всего git addих перед хранением. Тем не менее, я не уверен, что вы действительно хотите спрятать здесь - если вы хотите, чтобы эти изменения были частью ветки, с которой вы переключаетесь, зафиксируйте их. (Если вы намереваетесь вернуться к этой ветке и еще больше поработать над изменениями перед их фиксацией, то это stashможет быть правильным инструментом для работы.)
Cascabel
16
«Переключение ветвей несет с собой незафиксированные изменения» - это имеет смысл и, возможно, худшая дизайнерская идея. Какой смысл иметь ветки, если нельзя работать изолированно? !!!
nehem
1
В моем случае у меня есть одна функциональная ветка из ветки разработки. Я зафиксировал ветку функций, но она также показывает изменения, когда я проверяю ветку разработки.
Hitesh Garg
31

Краткий ответ: да, вам нужно сделать коммит. Однако убедитесь, что вы делаете это в правильной ветке!

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

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

git addэто команда для постановки изменений, которые вы затем зафиксируете. Он не записывает эти изменения в историю репозитория. Он просто помещает их в промежуточную область (индекс); git commitзатем использует содержимое этой промежуточной области для создания коммитов.

Cascabel
источник