On 2019-05-16, at 11:35 AM, Giorgio Forti <alvarmayo...@gmail.com> wrote:

> If I commit ONE file Git builds a "zip" that contains the actual situation of 
> ALL the 6 thousand of files in my C# solution? 
> And if I check out this commithe file Git gives me back the complete 
> situation at that moment?
> This would be the solution.
> This can work with files committed only locally and not pushed to the remote 
> repository?

So let me explain, if I can, the cheat that git uses.

Git's internal backing store is a write-once file system. Once a file goes into 
the "filesystem", it never changes. Since it never changes, the true internal 
name is the hash of the file.

Elsewhere, there are maps of user-visible-filenames to hash-filenames. And 
those maps are also files inside git's file system, and they have a 
hash-filename.

Please re-read those two bits twice more.

Alright, so what git does is this:
1. At any given moment, the "index" or "cache" contains the state of "what will 
be checked in next" -- and it consists of a full set of filename to hashname 
maps for the entire project.
2. On any given commit, the vast majority of files will not change, so the 
actual commit will have the same filename to hashname map as the last commit.
3. The actual commit is NOT the set of files, but the set of filename to 
hashname maps.

Please re-read number 3 there.

Git will store lots and lots of junk files over time. There is a separate 
mechanism that goes  through and finds all hash-filename files that are not 
referenced from any of the commit lists of user-filename to hash-filename maps, 
and cleans those out.

Git does not build a zip of all the 6000 files in your commit.
It builds a "zip" of the mappings of user-filenames to hash-filenames.

And, since this is a tree structure, ** if a directory does not change, it is 
reusing the same directory user filename to git-hash-filename map **.

The result is that when you change one file, all that changes is the directory 
object for the directory containing the filename of that object (because the 
user-filename now points to a different hash-filename), and all the parent 
directories back up to the root.

This is what makes git fast.

When you say "git add filename", the new file has been added to git's 
write-once backing store. And, the filename to hashname map in the index/cache 
has been updated.

That's one copy, one hash calculation, and one updating of a 40 byte hash 
record in a file. Plus possibly updating hash calculations and data for each 
parent directory.

After that, it's just a case of recording which new hash number is in use in 
various places.

This is git's cheat. It's just relying on unchanging hashes that have been 
mostly calculated in the past and are cheap to copy from A to B.

> I definitely recommend to learn about "git rebase -i" because you probably 
> will need it in near future. Git cherry-pick may help, too, if you are not 
> ready to learn about rebasing.

If you are looking to have to do a big, massive merge, which it sounds like ...

You will want to look into a tool called "imerge".  Git-imerge is a program 
that tries to solve the "massive merge" problem. It breaks the merge down into 
many, many, many little merges, most of which are automatic, and a tiny few 
will need your help with.

It makes the giant merge much less painful. Not pain-free. Less painful.

iMerge operates in two passes. Pass one does the merge, and absolutely clutters 
the history.
Pass 2 cleans up the history, and gives you a choice of either "This looks like 
a normal rebase", "This looks like a normal merge", or "This looks like a 
rebase, but keeps the history of how the changes were made". This last option 
*should* be the best choice, but at the moment it isn't. It leaves you with two 
sets of "history links" -- one set important, one set unimportant -- and there 
is no way to indicate to git which is which, and no tools to say "don't show 
these links by default". The result is that your history will look very messy, 
because the existing tools make assumptions that this system breaks.

---
This message was composed with the aid of a laptop cat, and no mouse

-- 
You received this message because you are subscribed to the Google Groups "Git 
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/git-users/079FDC79-DB83-408A-960B-0D1C9B4AF87A%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to