4 ms·
A git commit is a set of diffs, with respect to another commit. Commits are thus arcs+nodes, forming a graph. Each such commit has a unique name, locally and
by 10ren 16y ago
A git commit is a set of diffs, with respect to another commit.
Commits are thus arcs+nodes, forming a graph.
Each such commit has a unique name, locally and across all distributed copies. [actually a hash whose uniqueness is probabilistically "close enough"]
You can rearrange the graph, so that commits that previously formed independent branches of the graph are combined ("merged"). For commits with diffs on the same file, it either applies both diffs automatically, or detects that it can't do so safely, and demands manual help.
This is very cool.
--
(It seems to me) that the really clever parts of git are (1). the diff algorithm (which is old); and (2). the merge algorithm, including the detection (I don't know if it's old or new; maybe it's as simple as detecting overlap; but you want to prevent automatic merge if there's even a chance it might be wrong - probabilistic again).
What scares me about git is that there is no (simple) undo - and perhaps no undo at all in some cases; and that the commands aren't quite regular (like many unix tools). My experiments with it (doing weird things of course) often lead to messy, messed up graphs that I couldn't get out of.
It shouldn't be that hard. You have a bunch of nodes, you mix and match them one way, you mix them back.
--
I believe there exists (a). a very clean, clear, safe and regular model of these ideas that always works exactly as you'd expect; (b). a ui (commandline or gui) that reflects this model, simply and cleanly.
It's just that I don't know what it is.
- stevelosh 16y agoThe answer to (a) and (b) might be Mercurial. Each of its commands does one thing well. You combine them to do more complicated things. (Core) Mercurial basically has three concepts: repository, changesets (commits), and working directory. A repository holds changesets. You make new changesets by making your working directory look how you want it to and using 'hg commit'. You can "move around" the DAG with 'hg update'. You create a branch by committing while you're at a changeset that happens to already have a child (or several). You can use a label for the changesets on the branch (also called a "named branch" by Mercurial users) by running 'hg branch' first, if you like. You can merge branches with 'hg merge'. You move changesets between repositories with 'hg push' and 'hg pull'. There are a lot of extensions that add more features if you need them, but vanilla Mercurial has the cool things you talked about. It's safer than git -- there is no history rewriting built in except for the 'rollback' command, which is a one-step "undo" command. Once a changeset is in a repo it's there for good. There's no deleting of branches in a remote repo, no rebase --interactive, etc. It's also cleaner than git. For example, in git you can move to a different place in the DAG and create a new branch with 'git checkout -b foo SOMEREV'. With Mercurial you use two commands, each of which does a single thing: 'hg update' to move to the new position, and 'hg branch' to start a named branch. http://hg-scm.org/ http://hg-scm.org/