|
|
|
@ -48,7 +48,7 @@ $ git hash-object -w foo.txt |
|
|
|
|
257cc5642cb1a054f08cc83f2d943e56fd3ebe99 |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
You will now find an object in the store at: |
|
|
|
|
You will now find an object in the store: |
|
|
|
|
|
|
|
|
|
```bash |
|
|
|
|
$ find .git/objects -type f |
|
|
|
@ -64,7 +64,7 @@ $ git hash-object -w bar.txt |
|
|
|
|
257cc5642cb1a054f08cc83f2d943e56fd3ebe99 |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
That's right, nothing changed, this makes sense as we're only adding the content |
|
|
|
|
That's right, nothing changed! This makes sense as we're only adding the content |
|
|
|
|
to the object store! So how does Git remember the file names? |
|
|
|
|
|
|
|
|
|
## Filenames are part of tree objects |
|
|
|
@ -75,9 +75,11 @@ worktree, you will have a tree object. A tree object's content looks like: |
|
|
|
|
|
|
|
|
|
```code |
|
|
|
|
<mode> <type> <hash> <name> |
|
|
|
|
... |
|
|
|
|
<mode> <type> <hash> <name> |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
You can create this one for yourself by doing: |
|
|
|
|
You can create a tree object yourself by doing: |
|
|
|
|
|
|
|
|
|
```bash |
|
|
|
|
$ git update-index --add --cacheinfo 100644 \ |
|
|
|
@ -101,8 +103,8 @@ pointing too as well as some meta data. |
|
|
|
|
## Renaming |
|
|
|
|
|
|
|
|
|
Armed with the knowledge about trees and blobs, it should be fairly easy to |
|
|
|
|
understand what happens if you rename a file. To make not make it easier to |
|
|
|
|
understand, consider a simple example: we just rename a file at the top level. |
|
|
|
|
understand what happens if you rename a file. To make it easier to understand, |
|
|
|
|
consider a simple example: we just rename a file at the top level. |
|
|
|
|
|
|
|
|
|
> Note: more complex examples are just more time consuming to explain, but |
|
|
|
|
> not to understand. The same principles apply. |
|
|
|
@ -111,8 +113,9 @@ In case of such a rename, when you commit this rename, your repository will |
|
|
|
|
be impacted as follows: |
|
|
|
|
|
|
|
|
|
- The blob representing the file remains unchanged. |
|
|
|
|
- The top level tree object changes as it now has a different file name. |
|
|
|
|
- The commit object will point to the new tree. (It's parent will point to the |
|
|
|
|
- The top level tree object changes as well because the filename associated with |
|
|
|
|
the blob is different. |
|
|
|
|
- The commit object will point to the new tree. (Its parent will point to the |
|
|
|
|
old tree.) |
|
|
|
|
|
|
|
|
|
Nowhere is there any special mention of a rename occuring. Remember, we're just |
|
|
|
@ -124,12 +127,14 @@ However, that does not mean you lose your history when you rename a file. |
|
|
|
|
|
|
|
|
|
### How to see history of a renamed file |
|
|
|
|
|
|
|
|
|
Git might not store information on renames in it repository but it does come |
|
|
|
|
packed with an algorithm that detects file renames. For every add/delete pair |
|
|
|
|
added to the index, it determines how alike the paired files are. If they are |
|
|
|
|
at least 50% alike, it considered the pair to have been a rename. If there |
|
|
|
|
are multiple possibilities it takes the highest percentage one. If multipe files |
|
|
|
|
have the same percentage, it picks one depending on the implementation. |
|
|
|
|
Git might not store information on renames in the repository but it does come |
|
|
|
|
packed with an algorithm that detects file renames. The way it works is that for |
|
|
|
|
every add/delete pair added to the index, it tries to determine a rename |
|
|
|
|
candidate for every deleted file. It does this by comparing how similar the |
|
|
|
|
paired files are. If they are at least 50% similar, it considered the pair to |
|
|
|
|
have been a rename. If there are multiple rename candidates for one file, it |
|
|
|
|
takes the one with the highest similarity percentage. If multipe files have the |
|
|
|
|
same percentage, it picks one depending on the implementation. |
|
|
|
|
|
|
|
|
|
> **Note**: I believe, but am not sure, it basicaly takes the first |
|
|
|
|
> alphabeticaly match in the last case. |
|
|
|
@ -145,8 +150,8 @@ You can also turn off rename detection by doing `--no-renames` |
|
|
|
|
|
|
|
|
|
### Rename best practice |
|
|
|
|
|
|
|
|
|
Because of the treshold and the cheapness of commits, it is recommended that |
|
|
|
|
when you rename a file/directory. You commit those renames first, before you |
|
|
|
|
Because of the treshold and the cheapness of commits, it is recommended that |
|
|
|
|
when you rename a file/directory, you commit those renames first, before you |
|
|
|
|
continue working on the renamed file. This basically makes it so you can use |
|
|
|
|
a treshold of 100% all the time. |
|
|
|
|
|
|
|
|
|