8 ms·
Mike, Git seems unintuitive because you don't have a good grasp of what it does behind the scenes. Imagine trying to get to grips with a Unix shell, if you had
by weavejester 16y ago
Mike, Git seems unintuitive because you don't have a good grasp of what it does behind the scenes. Imagine trying to get to grips with a Unix shell, if you had no concept of files or directories. In such a scenario, even a simple command like "cat" would seem incomprehensible.
If you'll indulge me, I'd like to propose a thought experiment.
* * Designing a patch database * *
Consider you're responsible for administering a busy open source project. You get dozens of patches a day from developers and you find it increasingly difficult to keep track of them. How might you go about managing this influx of patch files?
The first thing you might consider is how do you know what each patch is supposed to do? How do you know who to contact about the patch? Or when the patch was sent to you?
The solution to this is not too tricky; you just add some metadata to the patch detailing the author, the date, a description of the patch and so forth.
The next problem you face is that some patches rely on other patches. For instance, Bob might publicly post a patch for a great new scheduler, but then Carol might post a patch correcting some bugs in Bob's code. Carol's patch cannot be applied without first applying Bob's patch.
So you allow each patch to have parents. The parent of Carol's patch would be Bob's patch.
You've solved two major problems, but now you face one final one. If you want to talk to other people about these patches, you need a common naming scheme. It's going to be problematic if you label a patch as ABC on your system, but a colleague labels a patch as XYZ. So you either need a central naming database, or some algorithm that can guarantee everyone gives the same label to the same patch.
Fortunately, we have such algorithms; they're called one-way hashes. You take the contents of the patch, its metadata and parents, serialize all of that and SHA1 the result.
Three perfectly logical solutions, and ones you may even have come up with yourself under similar circumstances.
* * Merging patches * *
Under this system, how would a merge be performed? Let's say you have two patches, A and B, and you want to combine them somehow. One way is to just apply each in turn to your source, fix any differences that can't be automatically resolved (conflicts), and then produce a new patch C from the combined diff.
That works, but now you have to store A, B and C in your patch database, and you don't retain any history. But wait! Your patches can have parents, so what if you created a 'merge' patch, M, with parents A and B?
A B
\ /
M
This is externally equivalent to what you did to produce C: patches A and B are applied to the source code, and then you apply M to resolve the differences. M will contain both the differences that can be resolved automatically, and any conflicts we have to resolve manually.
Having solved your problem, you write the code to your patch database and present the resulting program to your colleague.
* * A user tries to merge * *
"How do I merge?" he asks.
"I've written a tool to help you do that," you say, "Just specify the two patches you want to combine, and the tool will merge them together."
"Um, it says I have a merge conflict."
"Well, fix the problem, then tell the system to add your file to the 'merge patch' it's making."
Your colleague dutifully hacks away, and solves the conflict. "So I've fixed the file," he says, "But when I tell it to 'commit file' it fails."
"Remember, this is a patch database," you reply, "We're not dealing with files, we're dealing with patches. You have to add your file changes to your patch, and then commit the patch. You can't commit an individual file."
"What? That's not very intuitive," he grumbles, "Hey! I've added the file to the patch, but it tells me the merge isn't complete!"
"You need to add all of the files that have differences that were automatically resolved as well."
"Why?!"
"Because," you explain patiently, "You might not like the way those files have been changed. It needs your approval that the way it's resolved the differences is correct."
"Why to I have to re-commit everything my buddy has made?" he complains, "Seriously, I want to just commit one file. What the hell is up with your system?"
- viraptor 16y agoI see this mentioned so many times: "Git seems unintuitive because you don't have a good grasp of what it does behind the scenes" but I fail to see why this is true. Do we need to understand the implementation of block allocation, snapshots, atomic writes, etc. to save files? Do we need to know the ip checksumming algorithm to connect to use internet? Do we need to understand congestion control algorithms to browse websites? {and many other examples} No - we don't and many of us do not know those things. Then why are we expected to know the internals of git to use it? (use - not modify, analyse, edit without an interface, etc.) Why can't we get a tool which gets an address and makes the file appear on the local storage? (or any equivalent to VCS workflow) "Designing a patch database" - No, I want to use a VCS, not design it. If it works on pixie dust, I'm ok with that. It's just a tool. It's supposed to help me do the real work, not give more stuff to think about on every step. Why is "you don't understand how it works" an acceptable answer here? Where's the iphone of VCS-es?
- weavejester 16y ago"Do we need to understand the implementation of block allocation, snapshots, atomic writes, etc. to save files?" No, but consider what you need to know about file systems to use them. At the barest minimum, you need to know that: * Data is stored in files * Files have names * Files are contained in directories * Directories have names * Directories can contain directories If you had no understanding of what a file or a directory was, I'd imagine you'd find the behaviour of "grep" or "cat" completely unintuitive. You don't need to know how Git stores data internally, but you do need to have a basic understanding of its design, just as you need a basic understanding of a filesystem in order to use it.
- viraptor 16y agoI expect to need exactly the same level of knowledge to work with a DVCS, because I'm editing files. SVN was very close to providing that in many ways and it worked. I don't want to know about a staging area unless I explicitly use it, for example. I don't want to know about the design or patch handling, unless I explicitly request or apply a patch. Merging is merging - it's good couple of levels of abstraction above patches. Basically - I want my DVCS to require as much knowledge as cp, diff, patch. I could live with them, if I had to (see - `quilt`). Now a DVCS should be easier to use, not harder. Otherwise, what's the point?