Команда git stash. как прятать изменения в git

Partial stashes

Git allows choosing whether you want to stash just a single file, a bunch of files or individual changes within files. The git stash-p iterates through each hunk (a piece of change in Git) in the working copy and ask if you want to stash it or not:

diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
Stash this hunk [y,n,q,a,d,/,e,?]? y
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+
Stash this hunk [y,n,q,a,d,/,e,?]? n

Hunk Commands

Command Description
Search for a hunk by regex.
? Print help.
n Do not stash the hunk.
a Stash this hunk and all later hunks in the file.
d Do not stash this hunk or any of the later hunks in the file.
e Manually edit the current hunk
q Quit (selected hunks will be stashed)
s Split the hunk into smaller hunks.
y Stash the hunk.

Cómo guardar el trabajo en un stash

El comando coge los cambios sin confirmar (tanto los que están preparados como los que no los están), los guarda aparte para usarlos más adelante y, acto seguido, los deshace en el código en el que estás trabajando. Por ejemplo:

Llegados a este punto, tienes libertad para hacer cambios, crear confirmaciones, cambiar de rama y efectuar cualesquiera otras operaciones de Git; y, luego, regresar y volver a aplicar el stash cuando lo tengas todo listo.

Ten en cuenta que el stash es local para tu repositorio de Git y que los stashes no se transfieren al servidor cuando subes los cambios al repositorio remoto.

Undoing public changes

When working on a team with remote repositories, extra consideration needs to be made when undoing changes. should generally be considered a ‘local’ undo method. A reset should be used when undoing changes to a private branch. This safely isolates the removal of commits from other branches that may be in use by other developers. Problems arise when a reset is executed on a shared branch and that branch is then pushed remotely with . Git will block the push in this scenario complaining that the branch being pushed is out of date from the remote branch as it is missing commits.

The preferred method of undoing shared history is . A revert is safer than a reset because it will not remove any commits from a shared history. A revert will retain the commits you want to undo and create a new commit that inverts the undesired commit. This method is safer for shared remote collaboration because a remote developer can then pull the branch and receive the new revert commit which undoes the undesired commit.

Интерактивный rebase

rebase

  • pick (выбрать) — Поведение по умолчанию, используемое для каждого коммита в ветке, если вы не используете интерактивный режим. Оно означает, что данный коммит должен быть применен к своему (теперь уже переписанному) родительскому коммиту. При возникновении конфликтов rebase предложит вам их разрешить.
  • squash (сплющить)— Содержимое коммита будет «вложено» в содержимое предыдущего коммита. Это может быть сделано любое количество раз. Если взять вышеиспользованную для примера ветку и сплющить все ее коммиты (конечно же, кроме первого, который должен быть просто выбран), то новая ветка Z будет иметь единственный коммит поверх D. Это может быть полезным, если ваши изменения размазаны по множественным коммитам, но вы хотите, чтобы в истории они показывались как единый коммит.
  • edit (редактировать) — если вы пометите коммит таким образом, то процесс rebase остановится, а вы попадете в оболочку, где сможете совершить дополнительные необходимые изменения, после чего команда rebase —continue продолжит исполнение так, будто внесенные изменения были там изначально.
  • drop (выбросить) — если вы удалите коммит из интерактивного rebase, то он просто пропадет — так, будто никогда и не был сделан. Заметьте, что в этом случае возможны конфликты слияния, в случае если более поздние коммиты зависели от данных изменений.
  • объединения нескольких коммитов в один,
  • переупорядочивания коммитов,
  • удаления нежелательных изменений, о которых вы начали сожалеть,
  • перемещения вашей ветки на любой существующий коммит в репозитории,
  • изменения единичного коммита спустя значительное время после его создания.

rebaserebase

(тут переводчик снова тяжело вздыхает)

Multiple Stashes

You can run git stash several times so as to create multiple stashes, and then run git stash list to view them. By default, stashes are identified as a «WIP» – work in progress. It comes on top of the branch and commits that you created the stash from.

stash@{0}: WIP on master: 5002d47 our new homepage
stash@{1}: WIP on master: 5002d47 our new homepage
stash@{2}: WIP on master: 5002d47 our new homepage

It is good to add some context with git stash save "message"

By default, git stash pop will re-apply the last created stash: stash@{0}

You can choose which stash to re-apply like this:

Viewing stash diffs

Use git stash show to view a summary of a stash:

index.html | 1 +
style.css | 3 +++
2 files changed, 4 insertions(+)

You can also use the -p or --patch options to see the full diff of a stash:

diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+

The staging area

The primary function of the command, is to promote pending changes in the working directory, to the area. The staging area is one of Git’s more unique features, and it can take some time to wrap your head around it if you’re coming from an SVN (or even a Mercurial) background. It helps to think of it as a buffer between the working directory and the project history. The staging area is considered one of the «three trees» of Git, along with, the working directory, and the commit history.

Instead of committing all of the changes you’ve made since the last commit, the stage lets you group related changes into highly focused snapshots before actually committing it to the project history. This means you can make all sorts of edits to unrelated files, then go back and split them up into logical commits by adding related changes to the stage and commit them piece-by-piece. As in any revision control system, it’s important to create atomic commits so that it’s easy to track down bugs and revert changes with minimal impact on the rest of the project.

—soft

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

Здесь мы снова воспользовались командой , чтобы добавить измененный файл в раздел проиндексированных файлов. Чтобы убедиться, что индекс обновлен, посмотрим на вывод команды . Теперь в выводе команды строка «Changes to be committed» окрашена в зеленый цвет. Файл из предыдущего примера находится в рабочем каталоге как неотслеживаемый. Удалим его с помощью простой команды , поскольку в следующих примерах он нам больше не понадобится.

Теперь давайте мягко сбросим текущее состояние репозитория.

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

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

На данный момент в нашем репозитории находится три коммита. Мы выполним возврат к первому коммиту. Для этого нам потребуется идентификатор первого коммита. Его можно найти, просмотрев вывод команды .

Помните, что идентификаторы в истории коммитов уникальны для каждой системы. Это значит, что идентификатор коммита в этом примере будет отличаться от идентификатора, который вы увидите на вашей машине. Идентификатор интересующего нас коммита для этого примера — . Это идентификатор, соответствующий первичному коммиту «initial commit». Теперь укажем его в качестве целевого для нашей операции мягкого сброса.

Прежде чем вернуться назад во времени, давайте проверим текущее состояние репозитория.

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

Приведенный выше код выполняет «мягкий сброс», а также вызывает составную команду, которая включает команды и и выводит информацию о состоянии репозитория. Мы можем изучить эту информацию и сделать несколько интересных наблюдений. Во-первых, указывает на наличие изменений в файле и сообщает, что эти изменения проиндексированы для выполнения коммита. Во-вторых, входные данные указывают, что раздел проиндексированных файлов не изменился и SHA остался прежним: 67cc52710639e5da6b515416fd779d0741e3762e.

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

Теперь вывод команды log показывает, что в истории коммитов находится единственный коммит. Это четко иллюстрирует, что делает параметр . Как и при всех вызовах команды , сначала происходит сброс дерева коммитов. Наши предыдущие примеры с параметрами и воздействовали на указатель и не возвращали дерево коммитов в предыдущее состояние. Во время мягкого сброса происходит только сброс дерева коммитов.

Это может сбивать с толку: почему команда сообщает о наличии измененных файлов? Параметр не затрагивает раздел проиндексированных файлов, поэтому изменения в этом разделе сохраняются в истории коммитов. В этом можно убедиться, просмотрев вывод команды , показывающей, что SHA для файла остается неизменным. Напомним, что команда не показывает состояние «трех деревьев», она показывает различия между ними. В этом случае она показывает, что изменения в разделе проиндексированных файлов опережают изменения в истории коммитов, как если бы мы уже добавили их в индекс.

Wiederanwenden deiner im Stash aufbewahrten Änderungen

Zuvor aufbewahrte Änderungen kannst du mit erneut anwenden:

Wenn du deinen Stash poppst, werden die Änderungen aus deinem Stash entfernt und erneut auf deine Arbeitskopie angewendet.

Du kannst aber auch die Änderungen erneut auf deine Arbeitskopie anwenden und sie weiterhin in deinem Stash aufbewahren. Hierfür gibst du ein:

Das ist nützlich, wenn dieselben gestashten Änderungen auf mehrere Branches angewendet werden sollen.

Nachdem du nun die Grundlagen zum Stashing kennst, solltest du dir noch über einen kleinen Nachteil von bewusst werden: In den Standardeinstellungen bewahrt Git keine Änderungen an nicht verfolgten oder ignorierten Dateien im Stash auf.

Verwalten mehrerer Stashes

Du musst dich nicht auf einen einzigen Stash beschränken. Du kannst mehrmals ausführen, um mehrere Stashes zu erstellen, und diese anschließend mit anzeigen. Standardmäßig werden Stashes an der Spitze des Branchs und des Commits, aus dem du den Stash erstellt hast, einfach als «WIP» (Work in Progress) angegeben. Nach einer Weile kann es schwierig werden, sich daran zu erinnern, was im jeweiligen Stash enthalten ist:

Zur Bereitstellung von mehr Kontextinformationen ist es sinnvoll, deine Stashes mithilfe von mit einer Beschreibung zu versehen:

Standardmäßig wird mit der zuletzt erstellte Stash erneut angewendet:

Du kannst aber wählen, welcher Stash erneut angewendet werden soll, indem du dessen Kennung als letztes Argument anfügst, z. B.:

Fazer stash em arquivos ignorados ou não rastreados

Por padrão, executar o vai fazer o stash de:

  • alterações que foram adicionadas ao seu índice (alterações preparadas)
  • alterações feitas a arquivos que estão no momento rastreados pelo Git (alterações despreparadas)

No entanto, o stashing nãovai ser realizado em:

  • novos arquivos na cópia de trabalho que ainda não foram preparados
  • arquivos que foram ignorados

Ou seja, se a gente adiciona um terceiro arquivo ao exemplo acima, mas não o prepara (por exemplo, sem executar o ), o não vai executar o stashing nele.

Adicionar a opção (ou ) vai dizer ao para também fazer o stashing dos arquivos não rastreados:

Você também pode incluir alterações para arquivos ignorados, passando a opção (ou ) ao executar o .

Finding what is lost: Reviewing old commits

The whole idea behind any version control system is to store “safe” copies of a project so that you never have to worry about irreparably breaking your code base. Once you’ve built up a project history of commits, you can review and revisit any commit in the history. One of the best utilities for reviewing the history of a Git repository is the command. In the example below, we use to get a list of the latest commits to a popular open-source graphics library.

Each commit has a unique SHA-1 identifying hash. These IDs are used to travel through the committed timeline and revisit commits. By default, will only show commits for the currently selected branch. It is entirely possible that the commit you’re looking for is on another branch. You can view all commits across all branches by executing . The command  is used to view and visit other branches. Invoking the command, will return a list of all known branch names. One of these branch names can then be logged using .

When you have found a commit reference to the point in history you want to visit, you can utilize the command to visit that commit. is an easy way to “load” any of these saved snapshots onto your development machine. During the normal course of development, the usually points to or some other local branch, but when you check out a previous commit, no longer points to a branch—it points directly to a commit. This is called a “detached ” state, and it can be visualized as the following:

Checking out an old file does not move the pointer. It remains on the same branch and same commit, avoiding a ‘detached head’ state. You can then commit the old version of the file in a new snapshot as you would any other changes. So, in effect, this usage of on a file, serves as a way to revert back to an old version of an individual file. For more information on these two modes visit the page

Appliquer à nouveau vos changements stashés

Vous pouvez réappliquer les changements stashés au préalable grâce à la commande  :

L’éclatement de votre stash supprime les changements qu’il contient et les réapplique à votre copie de travail.

Vous pouvez également réappliquer les changements à votre copie de travail et les conserver dans votre stash grâce à la commande  :

C’est utile si vous souhaitez appliquer les mêmes changements stashés à plusieurs branches.

Maintenant que vous connaissez les bases du stash, soyez attentif à un point lorsque vous exécutez  : par défaut, Git ne fera pas de stash des changements apportés aux fichiers non suivis ou ignorés.

How git stash works

If you just wanted to know how to use , you can stop reading here. But if you’re curious about how Git (and ) works under the hood, read on!

Stashes are actually encoded in your repository as commit objects. The special ref at points to your most recently created stash, and previously created stashes are referenced by the ref’s reflog. This is why you refer to stashes by you’re actually referring to the nth reflog entry for the ref. Since a stash is just a commit, you can inspect it with :

Depending on what you stashed, a single operation creates either two or three new commits. The commits in the diagram above are:

  • , a new commit to store the tracked files that were in your working copy when you ran
  • ‘s first parent, the pre-existing commit that was at HEAD when you ran
  • ‘s second parent, a new commit representing the index when you ran
  • ‘s third parent, a new commit representing untracked files that were in your working copy when you ran . This third parent only created if:

    • your working copy actually contained untracked files; and
    • you specified the or option when invoked .

How encodes your worktree and index as commits:

  • Before stashing, your worktree may contain changes to tracked files, untracked files, and ignored files. Some of these changes may also be staged in the index.

  • Invoking encodes any changes to tracked files as two new commits in your DAG: one for unstaged changes, and one for changes staged in the index. The special ref is updated to point to them.

  • Using the option also encodes any changes to untracked files as an additional commit.

  • Using the option includes changes to any ignored files alongside changes to untracked files in the same commit.

When you run , the changes from the commits above are used to update your working copy and index, and the stash reflog is shuffled to remove the popped commit. Note that the popped commits aren’t immediately deleted, but do become candidates for future garbage collection.

Stashes parciais

Também é possível escolher fazer o stashing no único arquivo, uma coleção de arquivos, ou mudanças individuais de dentro de arquivos Se você passar a opção (ou ) ao , ele vai percorrer cada «fragmento» alterado na cópia de trabalho e perguntar se você quer fazer o stashing:

Você pode digitar ? para obter uma lista completa de comandos de fragmento. Os mais úteis são:

Comando Descrição
pesquisar um fragmento por regex
? ajuda
n não fazer stashing neste fragmento
q sair (o stashing vai ser feito em quaisquer fragmentos que já foram selecionados)
s dividir este fragmento em fragmentos menores
y fazer stashing neste fragmento

Não existe nenhum comando «abortar» explícito, no entanto, digitar (SIGINT) vai abortar o processo de stashing.

Aufnehmen von unverfolgten oder ignorierten Dateien in den Stash

In den Standardeinstellungen wird beim Ausführen von Folgendes in den Stash verschoben:

  • Änderungen, die deinem Index hinzugefügt wurden (in der Staging-Umgebung)
  • Änderungen an Dateien, die aktuell von Git verfolgt werden (noch nicht in der Staging-Umgebung)

Nicht in den Stash verschoben wird Folgendes:

  • Neue Dateien in deiner Arbeitskopie, die sich noch nicht in der Staging-Umgebung befinden
  • Dateien, die ignoriert wurden.

Wenn wir also dem obigen Beispiel eine dritte Datei hinzufügen, diese aber nicht in die Staging-Umgebung verschieben (d. h. wir führen nicht aus), fügt die Datei nicht dem Stash hinzu.

Durch Hinzufügen der Option (oder ) werden mit auch deine nicht verfolgten Daten gestasht:

Änderungen an ignorierten Dateien können miteinbezogen werden, indem du die Option (oder ) an den Befehl anfügst.

Faire un stash des fichiers non trackés ou ignorés

Par défaut, l’exécution de stashera :

  • les changements ajoutés à votre index (stagés) ;
  • les changements apportés aux fichiers actuellement suivis par Git (non stagés).

Mais cette commande ne stashera pas :

  • les nouveaux fichiers dans votre copie de travail qui n’ont pas encore été stagés ;
  • les fichiers qui ont été ignorés.

Par conséquent, si nous ajoutons un troisième fichier à notre exemple ci-dessus, mais que nous ne le stageons pas (autrement dit, nous n’exécutons pas ), ne les stashe pas.

Si vous ajoutez l’option  (ou ), vous demandez à de stasher également vos fichiers non suivis :

Vous pouvez également inclure des changements aux fichiers ignorés en transmettant l’option  (ou ) lorsque vous exécutez .

Принцип работы команды git stash

Если вы хотели получить сведения о том, как использовать команду , то дальше читать необязательно. Однако если вам необходимо узнать о принципах работы Git (и ) — продолжайте чтение!

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

В зависимости от отложенных элементов выполнение команды создаст два или три новых коммита. На схеме выше создаются следующие коммиты:

  •  — новый коммит для хранения отслеживаемых файлов, которые находились в рабочей копии при запуске команды ;
  • первый родитель  — существующий коммит, который при запуске команды находился в ветке, на которую указывал HEAD;
  • второй родитель  — новый коммит, выступавший в роли индекса при запуске команды ;
  • третий родитель  — новый коммит, представляющий неотслеживаемые файлы, которые находились в рабочей копии при запуске команды . Третий родитель создается, только если:
    • рабочая копия действительно содержит неотслеживаемые файлы, и
    • вы назначили опцию или команде .

Ниже показано, как команда шифрует рабочий каталог и индекс в виде коммитов:

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

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

  • Опция также позволяет шифровать все изменения неотслеживаемых файлов в виде дополнительного коммита.

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

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

Stashes partiels

Vous pouvez également choisir de stasher uniquement un fichier, une collection de fichiers ou des changements individuels depuis les fichiers. Si vous transmettez l’option  (ou ) à , elle itérera chaque « bloc » modifié dans votre copie de travail et vous demandera si vous souhaitez le stasher :

Appuyez sur ? pour obtenir une liste complète des commandes de bloc. Les plus fréquemment utilisées sont :

Commande Description
Rechercher un bloc par regex
? Aide
n Ne pas stasher ce bloc
q Quitter (tous les blocs déjà sélectionnés seront stashés)
s Diviser ce bloc en plus petits
y Stasher ce bloc

Il n’existe aucune commande « d’annulation », mais appuyer sur (SIGINT) annulera le processus de stash.

git stash の使用方法

の使用方法のみ知りたい場合はここで読むのをやめてもかまいませんが、Git (と ) の仕組みに関心がある場合は、このまま読み進んでください。

stash はコミットオブジェクトとしてご使用のリポジトリ内に実際にエンコードされます。 にある特別な ref は最近作成された最新の stash をポイントし、以前に作成された stash は ref の reflog により参照されます。このため、 で stash を参照すると、実際には ref の nth reflog エントリーを参照していることになります。stash は単なるコミットにすぎないため、 で調べることができます。

単一の 操作では、stash の内容に応じて 2 つまたは 3 つのコミットが新たに作成されます。上の図のコミットに関する説明は以下のとおりです。

  • : 実行時に作業コピー内の追跡対象ファイルを保存するための新しいコミット
  • の最初の親: 実行時に HEAD にあった既存のコミット
  • の 2 番目の親: 実行時にインデックスを表す新しいコミット
  • の 3 番目の親: 実行時に作業コピー内にあった追跡対象外のファイルを表す新しいコミット。3 番目の親は次の場合のみ作成される:

    • 作業コピーが実際に追跡対象外のファイルを含んでいた
    • 呼び出し時に または オプションを指定した

でワークツリーとインデックスをコミットとしてエンコードする仕組み:

  • stash する前に、作業ツリーに追跡対象ファイル、追跡対象外ファイル、および無視されたファイルに対する変更が含まれている場合があります。これらの変更の一部は、インデックスにステージングされている場合もあります。

  • を呼び出すと、DAG の2つの新しいコミットとして、追跡対象ファイルへの変更がすべてエンコードされます。1 つはステージングされていない変更で、もう 1 つはインデックスにステージングされた変更です。特別な ref が更新され、これらのコミットをポイントします。

  • オプションを使って追跡対象外ファイルへの変更を追加コミットとしてエンコードすることもできます。

  • オプションでは、無視されたファイルと追跡対象外のファイルへの変更を同じコミットに含めることができます。

を実行すると、上記のコミットの変更が作業コピーとインデックスの更新に使用されます。stash reflog がシャッフルされて、ポップされたコミットは削除されます。ポップされたコミットはすぐには削除されませんが、将来のガベージコレクションの候補になります。

Reset или не reset?

resetresetreset

Делаем hard reset

resetcheckoutreset —softreset -hard

git stash

  1. Он сохраняет вашу работу в хранилище (stash), откуда вы можете забрать ее назад в любой момент. Заметьте, что это хранилище не привязано к конкретной ветке, так что вы можете сохранить состояние вашего рабочего дерева в одной ветке, а позже наложить отличия на другую ветку.
  2. Stash возвращает ваше дерево в прошлое состояние, но в новой ветке. Так то если вы решите сделать коммит с вашими изменениями по сравнению с прошлым состоянием, вы не измените вашу оригинальную ветку.

reset —softreset —hardreset -hard

stashreset -hardstash

Funktionsweise von git stash

Wenn du lediglich wissen wolltest, wie man verwendet, musst du hier nicht weiterlesen. Aber lies weiter, wenn dich interessiert, was bei Git (und ) hinter den Kulissen geschieht!

Stashes sind übrigens in deinem Repository als Commit kodiert. Die spezielle Referenz verweist auf deinen zuletzt erstellten Stash. Früher erstellte Stashes werden über das Reflog der -Referenz referenziert. Deshalb referenzierst du Stashes über Du referenzierst eigentlich den n-ten Reflog-Eintrag für den . Da ein Stash einfach ein Commit ist, kannst du ihn mit untersuchen:

Je nachdem, was du stashst, werden in einem einzigen -Vorgang entweder zwei oder drei neue Commits erstellt. Im Beispiel oben sind es folgende Commits:

  • , ein neuer Commit zum Speichern der verfolgten Dateien, die sich beim Ausführen von in deiner Arbeitskopie befanden
  • Der erste übergeordnete Commit (Parent) von , d. h. der vorher bereits bestehende Commit, der sich am HEAD befand, als du ausgeführt hast
  • Der zweite Parent von  – ein neuer Commit, der den Index von dem Zeitpunkt repräsentiert, als du ausgeführt hast
  • Der dritte Parent von  – ein neuer Commit, der die nicht verfolgten Dateien repräsentiert, die sich in deiner Arbeitskopie befanden, als du ausgeführt hast. Der dritte Parent wird nur unter folgenden Voraussetzungen erstellt:
    • Deine Arbeitskopie enthält unverfolgte Dateien und
    • du hast die Option oder an angefügt.

So kodiert deinen Arbeitsbaum und deinen Index in Commits um:

  • Vor dem Stashing kann dein Arbeitsbaum Änderungen an verfolgten, nicht verfolgten und ignorierten Dateien enthalten. Einige dieser Änderungen befinden sich ggf. auch im Index (in der Staging-Umgebung).

  • Bei der Verwendung von werden alle Änderungen an verfolgten Dateien als zwei neue Commits in deinem DAG (gerichteten azyklischen Graphen) kodiert: ein Commit für die Änderungen, die sich nicht in der Staging-Umgebung befinden, und ein Commit für die Änderungen, die sich in der Staging-Umgebung (Index) befinden. Die spezielle Referenz wird aktualisiert, um auf diese Commits zu verweisen.

  • Mit der Option kannst du auch alle Änderungen an nicht verfolgten Dateien in einen weiteren Commit umkodieren.

  • Die Option schließt Änderungen an ignorierten Dateien genauso wie Änderungen an unverfolgten Dateien im selben Commit ein.

Wenn du ausführst, werden die Änderungen aus den obigen Commits zur Aktualisierung deiner Arbeitskopie und deines Index verwendet, und der hervorgeholte Commit wird aus dem Stash-Reflog entfernt. Beachte, dass die hervorgeholten Commits nicht sofort gelöscht werden, sondern zu Kandidaten für die nächste Bereinigung werden.

Ветвление

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

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

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

Стандартные команды:

  • — создаёт новую ветку с HEAD, указывающим на HEAD. Если не передать аргумент , то команда выведет список всех локальных веток;
  • — переключается на эту ветку. Можно передать опцию , чтобы создать новую ветку перед переключением;
  • — удаляет ветку.

Как наш локальный репозиторий, так и удалённый, могут иметь множество ветвей, поэтому когда вы отслеживаете удалённый репозиторий, на самом деле отслеживается удалённая ветка ( привязывает вашу ветку master к ветке origin/master удалённого репозитория).

Привязывание к удалённой ветке:

  • — привязывает текущую ветку к указанной удалённой ветке;
  • — аналог предыдущей команды;
  • — создаёт новую локальную ветку и начинает отслеживать удалённую;
  • — показывает локальные и отслеживаемые удалённые ветки;
  • — создаёт локальную ветку с таким же именем, как у удалённой, и начинает её отслеживать.

В общем, связан с изменением места, на которое указывает HEAD ветки, что похоже на то, как перемещает общий HEAD.

Прятки и чистка

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

Прим. перев. Это не совсем так. При некоторых обстоятельствах Git может автоматически перенести незафиксированное изменение в другую ветку.

Однако порой у вас есть незавершённые изменения, которые нельзя фиксировать. В такой ситуации их можно сохранить и «спрятать» с помощью команды . Чтобы вернуть изменения, используйте .

Возможно, вместо этого вы захотите стереть все внесённые изменения. В таком случае используйте команду . Опция также удалит неотслеживаемые файлы. Совет: добавьте опцию , чтобы увидеть, что произойдёт при запуске без непосредственного использования.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *