On Thu, 27 Dec 2012 17:46:21 -0800 (PST) Mark Green <drmoos...@gmail.com> wrote:
> I've been reading through the Pro Git book online and it's very > interesting, but I'm wondering about some of the plumbing commands > and how some of the things Git does can be simulated. For example: > > - If you are going to use hash-object to put a blob into the > database, is there a way to tell if an identical blob is already > there? Do you just go ahead and hash-object anyway and nothing in the > database will change because the SHA1 and the content will both be > the same? The latter. You just go ahead and `git hash-object -w` makes sure the blob which the specified contents is in the database no matter if it's already there or is required to be written there. > - Is there a plumbing way to identify if it is safe to perform a > "commit" and update the db, or if a merge is required first because > the repo has been changed elsewhere? You seem to be somewhat confused about the concepts. The repository maintains "objects" (commits, trees and blobs; interlinked with each other) and "symbolic references" onto them -- branches and tags. The only thing about "merges" the repository "knows" is that merge commits refer to more than one parent commits (usually two, may be more). The repository also maintains its configuration, which, among other things, keeps track of "named remotes" and records which local branches track which remote branches. This is the only information which is known to Git about how different branches relate to each other; everything else belongs to the domain of the programmer's mind. Now we should separate the concepts. The state of "being safe to commit" is just the state of the repository's object database being (advisary) locked by a Git process so it can assume no other Git process will try to update that database at the same time. It then proceeds with doing whatever is needed to update the database to record the new commit. After updating the database (and possibly a symbolic ref, in case of committing while being on a branch) the lock is removed. The state of requiring a merge could only be decided by the programmer, and has nothing to do with committing: a need to merge someone else's work might arise from a *push* conflict, when you're trying to push your commits and discover someone pushed before you and so you're now in need to reconcile their changes with yours (by fetching and then merging their work or by rebasing yours onto theirs). --