Вопрос по git, branch – Git постановка и фиксация между несколькими ветвями

11

Я совершенно не понимаю мерзавца. Вот что я получаю:

<code>git branch  (outputs that I'm on master)
git checkout -b foo
echo "next line" >> file (file is an existing file)
git add file (stages)
git checkout master
git status (shows that file has "next line" and is staged!!)
git commit (commits the changes that were staged on branch foo!!)
git checkout foo
</code>

Вот кикер. foo теперь не показывает какие-либо изменения, внесенные в файл в рабочем каталоге ИЛИ на стадии.

Похоже, что любые изменения, которые вы вносите, включая изменение файлов и размещение, происходят со ВСЕМИ ветвями. и когда вы передаете COMMIT в определенную ветку, эти изменения отменяются во всех других ветках, кроме той, в которую вы зафиксировали.

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

Редактировать для явного примера:

<code>$ mkdir element
$ cd element
$ git init
Initialized empty Git repository in /home/dan/element/.git/
$ echo "one" >> one
$ git add one
$ git commit -m msg
[master (root-commit) 36dc8b0] msg
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 one
$ git checkout -b fire
Switched to a new branch 'fire'
$ echo "next line" >> one
$ git checkout master
M       one
Switched to branch 'master'
$ cat one
one
next line
$
</code>

Что явно противоречит этому из книги про git:

This is an important point to remember: Git resets your working directory to look like the snapshot of the commit that the branch you check out points to. It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it.

Помогает ли мой ответ прояснить ситуацию? Я думаю, что это предшествует вашему редактированию, но я не совсем уверен. larsks

Ваш Ответ

2   ответа
9

Неважно, на какой ты ветке, когда тыДобавлят файл, только когда вы Совершить Это. Так что, если вы сделаете это:

git add file
git checkout master
git commit

Вы отправили файл в главную ветвь.

Вот полный пример с выводом. Начнем с нового репозитория:

$ git init
Initialized empty Git repository in /home/lars/tmp/so/repo/.git/

На данный момент мы находимся наmaster branch и мы еще не добавили ни одного файла. Давайте добавим файл:

$ date > file1
$ cat file1
Fri May 11 13:05:59 EDT 2012
$ git add file1
$ git commit -m 'added a file'
[master (root-commit) b0764b9] added a file
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 file1

Отлично, теперь у нас есть ветка master) с одним коммитом. Давайте создадим новую ветку:

$ git checkout -b foo
Switched to a new branch 'foo'
$ git branch
* foo
  master
$ ls
file1

Теперь мы добавим строку вfile1.

$ date >> file1
$ git status
# On branch foo
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   file1
#
no changes added to commit (use "git add" and/or "git commit -a")

Это показывает, что файл был изменен, но еще не подготовлен. Давайте подготовим файл и передадим его:

$ git add file1
$ git commit -m 'made a change'
[foo 761bed9] made a change
 1 files changed, 1 insertions(+), 0 deletions(-)

И перезапуститьgit status:

$ git status
# On branch foo
nothing to commit (working directory clean)

На данный момент файл выглядит следующим образом:

Fri May 11 13:05:59 EDT 2012
Fri May 11 13:07:36 EDT 2012

Если мы вернемся кmaster ветвь, мы увидим более раннюю версию файла без второй строки:

$ git checkout master
Switched to branch 'master'
$ cat file1
Fri May 11 13:05:59 EDT 2012

Изменения в файле изолированы от ветви, в которой они были зафиксированы.

В твоем обновленном примере это ...

$ git checkout master

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

Да - если вы работаете на ветке атомарно по отношению к коммитам, все работает как в этом примере, и это имеет смысл для меня. Если вы изменяете и, возможно, ставите без коммитов, а затем переключаете ветки, то вы переходите в это странное зацикленное состояние, которое произошло в моем первом посте. Разве мораль просто никогда не переключает ветви без совершения? Однако: если я делаю это в другом направлении и работаю над мастером и переключаюсь на ответвление, это дает мне ошибку:error: You have local changes to 'one'; cannot switch branches. Не знаю, почему я не получил эту ошибку, работая в другом направлении. djechlin
Был ли файл отслежен перед запускомgit add? Можете ли вы переосмыслить свой вопрос, используя пример репозитория, показывающий фактические команды и вывод? В общем, обычно либо коммит, либо Притон ваши изменения до смены веток. larsks
Я добавил к этому ответу. larsks
Отредактированный вопрос, чтобы показать полный диалог, а не только команды. Я посмотрю в тайник - кажется, я не понимаю, как на самом деле "мелкие" ветки в git. Я не понимаю, почему Git позволил мне сделать грязную проверку. djechlin
Я думаю, что вижу. Пока ветви указывают на один и тот же рабочий каталог, вы можете свободно переключаться. После того, как вы подтвердите один из них, и они укажут на разные снимки, git не позволит вам делать грязные проверки. djechlin
2

или индекс, является общим для всех ветвей, что объясняет ваши наблюдения

Похожие вопросы