You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reset demystified: Some semantic cleanup, and much de-capitalization
In addition to some semantic tidying up, de-capitalize the terms
"index" and "working directory", as those terms are not normally
capitalized in the official Git docs.
Signed-off-by: Robert P. J. Day <[email protected]>
Copy file name to clipboardExpand all lines: book/07-git-tools/sections/reset.asc
+27-27Lines changed: 27 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -51,7 +51,7 @@ The Git `cat-file` and `ls-tree` commands are ``plumbing'' commands that are use
51
51
[[_the_index]]
52
52
===== The Index
53
53
54
-
The Index is your *proposed next commit*.
54
+
The _index_ is your *proposed next commit*.
55
55
We've also been referring to this concept as Git's ``Staging Area'' as this is what Git looks at when you run `git commit`.
56
56
57
57
Git populates this index with a list of all the file contents that were last checked out into your working directory and what they looked like when they were originally checked out.
@@ -71,10 +71,10 @@ The index is not technically a tree structure -- it's actually implemented as a
71
71
72
72
===== The Working Directory
73
73
74
-
Finally, you have your working directory.
74
+
Finally, you have your _working directory_ (also commonly referred to as the ``working tree'').
75
75
The other two trees store their content in an efficient but inconvenient manner, inside the `.git` folder.
76
-
The Working Directory unpacks them into actual files, which makes it much easier for you to edit them.
77
-
Think of the Working Directory as a *sandbox*, where you can try changes out before committing them to your staging area (index) and then to history.
76
+
The working directory unpacks them into actual files, which makes it much easier for you to edit them.
77
+
Think of the working directory as a *sandbox*, where you can try changes out before committing them to your staging area (index) and then to history.
78
78
79
79
[source,console]
80
80
----
@@ -90,7 +90,7 @@ $ tree
90
90
91
91
==== The Workflow
92
92
93
-
Git's main purpose is to record snapshots of your project in successively better states, by manipulating these three trees.
93
+
Git's typical workflow is to record snapshots of your project in successively better states, by manipulating these three trees.
94
94
95
95
image::images/reset-workflow.png[]
96
96
@@ -100,38 +100,38 @@ Now we run `git init`, which will create a Git repository with a HEAD reference
100
100
101
101
image::images/reset-ex1.png[]
102
102
103
-
At this point, only the Working Directory tree has any content.
103
+
At this point, only the working directory tree has any content.
104
104
105
-
Now we want to commit this file, so we use `git add` to take content in the Working Directory and copy it to the Index.
105
+
Now we want to commit this file, so we use `git add` to take content in the working directory and copy it to the index.
106
106
107
107
image::images/reset-ex2.png[]
108
108
109
-
Then we run `git commit`, which takes the contents of the Index and saves it as a permanent snapshot, creates a commit object which points to that snapshot, and updates `master` to point to that commit.
109
+
Then we run `git commit`, which takes the contents of the index and saves it as a permanent snapshot, creates a commit object which points to that snapshot, and updates `master` to point to that commit.
110
110
111
111
image::images/reset-ex3.png[]
112
112
113
113
If we run `git status`, we'll see no changes, because all three trees are the same.
114
114
115
115
Now we want to make a change to that file and commit it.
116
-
We'll go through the same process; first we change the file in our working directory.
116
+
We'll go through the same process; first, we change the file in our working directory.
117
117
Let's call this *v2* of the file, and indicate it in red.
118
118
119
119
image::images/reset-ex4.png[]
120
120
121
-
If we run `git status` right now, we'll see the file in red as ``Changes not staged for commit,'' because that entry differs between the Index and the Working Directory.
122
-
Next we run `git add` on it to stage it into our Index.
121
+
If we run `git status` right now, we'll see the file in red as ``Changes not staged for commit,'' because that entry differs between the index and the working directory.
122
+
Next we run `git add` on it to stage it into our index.
123
123
124
124
image::images/reset-ex5.png[]
125
125
126
-
At this point, if we run `git status`, we will see the file in green under ``Changes to be committed'' because the Index and HEAD differ -- that is, our proposed next commit is now different from our last commit.
126
+
At this point, if we run `git status`, we will see the file in green under ``Changes to be committed'' because the index and HEAD differ -- that is, our proposed next commit is now different from our last commit.
127
127
Finally, we run `git commit` to finalize the commit.
128
128
129
129
image::images/reset-ex6.png[]
130
130
131
131
Now `git status` will give us no output, because all three trees are the same again.
132
132
133
133
Switching branches or cloning goes through a similar process.
134
-
When you checkout a branch, it changes *HEAD* to point to the new branch ref, populates your *Index* with the snapshot of that commit, then copies the contents of the *Index* into your *Working Directory*.
134
+
When you checkout a branch, it changes *HEAD* to point to the new branch ref, populates your *index* with the snapshot of that commit, then copies the contents of the *index* into your *working Directory*.
135
135
136
136
==== The Role of Reset
137
137
@@ -159,14 +159,14 @@ With `reset --soft`, it will simply stop there.
159
159
160
160
Now take a second to look at that diagram and realize what happened: it essentially undid the last `git commit` command.
161
161
When you run `git commit`, Git creates a new commit and moves the branch that HEAD points to up to it.
162
-
When you `reset` back to `HEAD~` (the parent of HEAD), you are moving the branch back to where it was, without changing the Index or Working Directory.
163
-
You could now update the Index and run `git commit` again to accomplish what `git commit --amend` would have done (see <<_git_amend>>).
162
+
When you `reset` back to `HEAD~` (the parent of HEAD), you are moving the branch back to where it was, without changing the index or working directory.
163
+
You could now update the index and run `git commit` again to accomplish what `git commit --amend` would have done (see <<_git_amend>>).
164
164
165
165
===== Step 2: Updating the Index (--mixed)
166
166
167
-
Note that if you run `git status` now you'll see in green the difference between the Index and what the new HEAD is.
167
+
Note that if you run `git status` now you'll see in green the difference between the index and what the new HEAD is.
168
168
169
-
The next thing `reset` will do is to update the Index with the contents of whatever snapshot HEAD now points to.
169
+
The next thing `reset` will do is to update the index with the contents of whatever snapshot HEAD now points to.
170
170
171
171
image::images/reset-mixed.png[]
172
172
@@ -178,7 +178,7 @@ You rolled back to before you ran all your `git add` and `git commit` commands.
178
178
179
179
===== Step 3: Updating the Working Directory (--hard)
180
180
181
-
The third thing that `reset` will do is to make the Working Directory look like the Index.
181
+
The third thing that `reset` will do is to make the working directory look like the index.
182
182
If you use the `--hard` option, it will continue to this stage.
183
183
184
184
image::images/reset-hard.png[]
@@ -187,31 +187,31 @@ So let's think about what just happened.
187
187
You undid your last commit, the `git add` and `git commit` commands, *and* all the work you did in your working directory.
188
188
189
189
It's important to note that this flag (`--hard`) is the only way to make the `reset` command dangerous, and one of the very few cases where Git will actually destroy data.
190
-
Any other invocation of `reset` can be pretty easily undone, but the `--hard` option cannot, since it forcibly overwrites files in the Working Directory.
190
+
Any other invocation of `reset` can be pretty easily undone, but the `--hard` option cannot, since it forcibly overwrites files in the working directory.
191
191
In this particular case, we still have the *v3* version of our file in a commit in our Git DB, and we could get it back by looking at our `reflog`, but if we had not committed it, Git still would have overwritten the file and it would be unrecoverable.
192
192
193
193
===== Recap
194
194
195
195
The `reset` command overwrites these three trees in a specific order, stopping when you tell it to:
196
196
197
197
1. Move the branch HEAD points to _(stop here if `--soft`)_
198
-
2. Make the Index look like HEAD _(stop here unless `--hard`)_
199
-
3. Make the Working Directory look like the Index
198
+
2. Make the index look like HEAD _(stop here unless `--hard`)_
199
+
3. Make the working directory look like the index
200
200
201
201
==== Reset With a Path
202
202
203
203
That covers the behavior of `reset` in its basic form, but you can also provide it with a path to act upon.
204
204
If you specify a path, `reset` will skip step 1, and limit the remainder of its actions to a specific file or set of files.
205
205
This actually sort of makes sense -- HEAD is just a pointer, and you can't point to part of one commit and part of another.
206
-
But the Index and Working directory _can_ be partially updated, so reset proceeds with steps 2 and 3.
206
+
But the index and working directory _can_ be partially updated, so reset proceeds with steps 2 and 3.
207
207
208
208
So, assume we run `git reset file.txt`.
209
209
This form (since you did not specify a commit SHA-1 or branch, and you didn't specify `--soft` or `--hard`) is shorthand for `git reset --mixed HEAD file.txt`, which will:
210
210
211
211
1. Move the branch HEAD points to _(skipped)_
212
-
2. Make the Index look like HEAD _(stop here)_
212
+
2. Make the index look like HEAD _(stop here)_
213
213
214
-
So it essentially just copies `file.txt` from HEAD to the Index.
214
+
So it essentially just copies `file.txt` from HEAD to the index.
215
215
216
216
image::images/reset-path1.png[]
217
217
@@ -228,8 +228,8 @@ We would just run something like `git reset eb43bf file.txt`.
228
228
229
229
image::images/reset-path3.png[]
230
230
231
-
This effectively does the same thing as if we had reverted the content of the file to *v1* in the Working Directory, ran `git add` on it, then reverted it back to *v3* again (without actually going through all those steps).
232
-
If we run `git commit` now, it will record a change that reverts that file back to *v1*, even though we never actually had it in our Working Directory again.
231
+
This effectively does the same thing as if we had reverted the content of the file to *v1* in the working directory, ran `git add` on it, then reverted it back to *v3* again (without actually going through all those steps).
232
+
If we run `git commit` now, it will record a change that reverts that file back to *v1*, even though we never actually had it in our working directory again.
233
233
234
234
It's also interesting to note that like `git add`, the `reset` command will accept a `--patch` option to unstage content on a hunk-by-hunk basis.
235
235
So you can selectively unstage or revert content.
@@ -268,7 +268,7 @@ Like `reset`, `checkout` manipulates the three trees, and it is a bit different
268
268
Running `git checkout [branch]` is pretty similar to running `git reset --hard [branch]` in that it updates all three trees for you to look like `[branch]`, but there are two important differences.
269
269
270
270
First, unlike `reset --hard`, `checkout` is working-directory safe; it will check to make sure it's not blowing away files that have changes to them.
271
-
Actually, it's a bit smarter than that -- it tries to do a trivial merge in the Working Directory, so all of the files you _haven't_ changed will be updated.
271
+
Actually, it's a bit smarter than that -- it tries to do a trivial merge in the working directory, so all of the files you _haven't_ changed will be updated.
272
272
`reset --hard`, on the other hand, will simply replace everything across the board without checking.
273
273
274
274
The second important difference is how `checkout` updates HEAD.
0 commit comments