{"thread":{"id":"8055","subject":"svn user trying to recover from brain damage","startedAt":"2007-05-09T15:30:18Z","lastAt":"2007-05-11T17:29:31Z","messageCount":8,"participants":["Joshua Ball","Carl Worth","Karl Hasselström","Petr Baudis","Linus Torvalds","J. Bruce Fields","Jan Hudec","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"41604","messageId":"92fdc3450705090830t64c8f5b9r4af277807dfe834d@mail.gmail.com","threadId":"8055","inReplyTo":null,"subject":"svn user trying to recover from brain damage","fromName":"Joshua Ball","fromEmail":"sciolizer@gmail.com","sentAt":"2007-05-09T15:30:18Z","receivedAt":"2007-05-09T15:30:18Z","isPatch":false,"sender":{"key":"sciolizer@gmail.com","avatar":null},"body":"Hi all,\n\nThe git page says that this mailing list is for \"bug reports, feature\nrequests, comments and patches\". Is there a mailing list for new users\ncrying out for help? If so, forward me there.\n\nOK, I'm feeling very frustrated right now, so let me just say that git\ndocumentation sucks. All the documentation I can find anywhere falls\ninto two categories:\n\n1. Tutorials for people brand new to version control, with just enough\ninformation for them to \"obey the rules\", but completely empty of any\ninformation that could help them exploit the real power of\ndecentralized version control.\n2. Technical documentation which assumes pre-obtained knowledge.\n\nNow that I've insulted you and am probably not on your good side...\n\nWhat the heck do these terms mean? The glossary on the Git wiki was\nunhelpful (I'll explain later). BTW, what is wrong with the wiki?\n(Particularly the excessive [grayed-out text [no match, add rest:\n\"used by any common UNIX command. The fact that it is a\nmispronunciation of \"]]. Is this some new kind of spam, or a buggy\nwiki feature?)\n\nHEAD\nHEAD REF\nworking tree\nobject\nbranch\nmerge\nmaster\ncommit (as in the phrase \"bring the working tree to a given commit\")\n\nWhile the Git wiki does in fact define all of these, it doesn't answer\nany of my questions about those terms:\n\nIs there a difference between HEAD and the working tree?\nDoes HEAD change when I cg-switch/git-checkout?\nWhat is an object? Is it a set of patches? A tree snapshot?\nWhat the heck is a branch? (Why does it have so many different\ndefinitions? I feel like every time I come across \"branch\" in the man\npages, it means something different.)\n\nMore on branches: The wiki says that a group of commits linked\ntogether form a DAG. Does that mean every fork/clone/branch-create\npossibly doubles the number of branches. So if I fork and then\nremerge, do I have two branches?\n\nA -> B -> D\nA -> C -> D\n\nWould D be the head of this branch? If so, then heads do not uniquely\nidentify a branch?\n\nIs there a standard revision notation? (Where my definition of\n\"revision\" is a tree snapshot. In SVN, it would be identified by a\nnumber.) `cg-diff -r A..B` works fine if A and B are branches, but how\ndo I diff from an older revision to a newer revision? Can I diff\nbetween two revisions which haven't shared the same parent since 2006?\n\nWhat about the master branch? Is there anything special about it? By\nspecial I mean, do any of the git or cogito commands implicitly assume\nthat you are working with master? If git is truly decentralized, then\nwouldn't master be on an equal footing with all other branches?\n\nWhat is a merge? My understanding of merge comes from the SVN book,\nwhere it was described as diff+apply. Diff takes 2 arguments, and\napply takes a 1 argument (if the patch is implicit). However, cg-merge\nonly appears to take one branch. (There again a use of the word\nbranch! Wouldn't commit or revision be a more accurate term?) Why does\ncg-merge only take one argument? Even if I use the -b switch, I'm\nstill only up to two arguments. Where is the hidden argument?\n\nLastly, the most important question of all, which may answer many of\nthe questions above:\n\nCan you fill in the missing pieces, making corrections where\nnecessary? (recommend unispace font)\n\nCommand     |   Reads               |   Writes\ncg-fetch    | remote branch         | corresponding branch in local respository\ncg-commit   | working copy          | HEAD\ncg-update   | remote branch         | working copy AND HEAD\ncg-merge    | branch & working copy | working copy\ncg-diff     | arguments             | STDOUT\ncg-push     |                       | remote branch (usually origin)\ncg-pull     | remote branch         |\ncg-restore  |                       |\n\nPerhaps the Reads column should be split into two, like ReadInfo and ReadSafety.\nReadInfo would say which revision/branch/commit/object is being read for actual\ncontent, while ReadSafety is only read to make sure that nothing will be lost\nafter running the command. (e.g., cg-update reads the working copy to make sure\nthat you are not in a partial merge, but once it knows that it is safe, it\nignores the contents of working directory. I may have this totally wrong.)\n\nOn cg-fetch, is the remote branch necessarily remote? Or can you fetch\nfrom local\ncg-switch-branches? What does \"corresponding branch in local\nrepository\" mean? Does cg-fetch touch your working copy?\n\nWhat is the difference between cg-restore and cg-seek?\n\nPlease reply even if you can only answer one of my many questions! If\nI can grab just one fact and say about it, \"This is truth\", then it\ngives me a rock to stand on amidst all the term-mashing out there.\n\nIn the words of Dijkstra, \"Since breaking out of bad habits, rather\nthan acquiring new ones, is the toughest part of learning, we must\nexpect from that system permanent mental damage for most ... exposed\nto it.\"\n\nMay you lead me to a quick recovery. Hail to decentralized version control.\n\nJosh \"Ua\" Ball\n"},{"id":"41609","messageId":"874pmmkmsq.wl%cworth@cworth.org","threadId":"8055","inReplyTo":"92fdc3450705090830t64c8f5b9r4af277807dfe834d@mail.gmail.com","subject":"Re: svn user trying to recover from brain damage","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2007-05-09T16:02:29Z","receivedAt":"2007-05-09T16:02:29Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Wed, 9 May 2007 10:30:18 -0500, \"Joshua Ball\" wrote:\n> Is there a difference between HEAD and the working tree?\n\nYes. HEAD is a pointer to committed state. HEAD is an alias for the\ncurrent branch.\n\n> Does HEAD change when I cg-switch/git-checkout?\n\nYes.\n\n> What is an object?\n\nIt's a low-level aspect of git's unified storage model. The various\nobject types, (blob, tree, commit, tag),  are defined quite clearly in\nthe documentation.\n\n> What the heck is a branch?\n\nSimply a pointer to the DAG that moves as new commits are created\nwhile \"on\" that branch.\n\n> More on branches: The wiki says that a group of commits linked\n> together form a DAG.\n\nYes.\n\n>                      Does that mean every fork/clone/branch-create\n> possibly doubles the number of branches.\n\nNo. Creating a new branch simply references some existing commit in\nthe DAG already.\n\n>                                           So if I fork and then\n> remerge, do I have two branches?\n>\n> A -> B -> D\n> A -> C -> D\n\nNo. If you merged you would have history that looks like this:\n\n /-> B -\\\nA        D\n \\-> C -/\n\n> Is there a standard revision notation?\n\nYes. See the documentation for git-rev-parse and the section on\nspecifing revisions, (hint: when you run a command like \"git log\" and\nsee long sequence of hex characters, you can use those (or abbreviated\nversions of those) to name revisons). You can also do many other\nthings as described in the documentation.\n\n[Beyond this point you bring in too many svn misconceptions to make\nthe questions easy to answer.]\n\n-Carl\n"},{"id":"41611","messageId":"20070509161217.GA19368@diana.vm.bytemark.co.uk","threadId":"8055","inReplyTo":"874pmmkmsq.wl%cworth@cworth.org","subject":"Re: svn user trying to recover from brain damage","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-05-09T16:12:17Z","receivedAt":"2007-05-09T16:12:17Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-05-09 09:02:29 -0700, Carl Worth wrote:\n\n> [Beyond this point you bring in too many svn misconceptions to make\n> the questions easy to answer.]\n\nBut do feel free to come with follow-up questions, Joshua! We usually\ntry our best to be friendly and helpful here, even if it's hard\nsometimes not to say mean things about other SCMs. :-)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"41614","messageId":"20070509162259.GY4489@pasky.or.cz","threadId":"8055","inReplyTo":"92fdc3450705090830t64c8f5b9r4af277807dfe834d@mail.gmail.com","subject":"Re: svn user trying to recover from brain damage","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-09T16:22:59Z","receivedAt":"2007-05-09T16:22:59Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"  Hi,\n\nOn Wed, May 09, 2007 at 05:30:18PM CEST, Joshua Ball wrote:\n> The git page says that this mailing list is for \"bug reports, feature\n> requests, comments and patches\". Is there a mailing list for new users\n> crying out for help? If so, forward me there.\n\n  I think it fits in the \"comments\" category. :-)\n\n> OK, I'm feeling very frustrated right now, so let me just say that git\n> documentation sucks. All the documentation I can find anywhere falls\n> into two categories:\n> \n> 1. Tutorials for people brand new to version control, with just enough\n> information for them to \"obey the rules\", but completely empty of any\n> information that could help them exploit the real power of\n> decentralized version control.\n> 2. Technical documentation which assumes pre-obtained knowledge.\n> \n> Now that I've insulted you and am probably not on your good side...\n> \n> What the heck do these terms mean? The glossary on the Git wiki was\n> unhelpful (I'll explain later). BTW, what is wrong with the wiki?\n> (Particularly the excessive [grayed-out text [no match, add rest:\n> \"used by any common UNIX command. The fact that it is a\n> mispronunciation of \"]]. Is this some new kind of spam, or a buggy\n> wiki feature?)\n\n  Sorry, it was a bug-ridden wiki. I was desperately trying to debug\nsome weird behaviour, few moments ago I've finally nailed it down and\nall should be fine now.\n\n> HEAD\n> HEAD REF\n> working tree\n> object\n> branch\n> merge\n> master\n> commit (as in the phrase \"bring the working tree to a given commit\")\n> \n> While the Git wiki does in fact define all of these, it doesn't answer\n> any of my questions about those terms:\n> \n> Is there a difference between HEAD and the working tree?\n\n  This is (unfortunately) case-sensitive:\n\n  HEAD identifies the commit (our slightly confusing name for a\nrevision) that corresponds to your working tree - usually the latest\ncommit in your current branch (by default 'master').\n\n  head is just the latest commit in a branch, any branch.\n\n> Does HEAD change when I cg-switch/git-checkout?\n\n  Yes, HEAD changes (starts pointing to your new branch) when you\ncg-switch or git-checkout -b.\n\n> What is an object? Is it a set of patches? A tree snapshot?\n\n  Object is the basic unit of stored data Git works with. object may be\neither:\n\n\t\"blob\" - file at a particular point of time\n\t\"tree\" - list of files, corresponding to a particular directory\n\t         (again at a particular point of time)\n\t\"commit\" - one revision in the project history; contains\n\t           information about the parent commit(s), who did\n\t           the commit, the commit message and link to the\n\t           corresponding root tree object\n\t\"tag\" - links to another object, with additional information\n\t        like who/when made the tag and the tag comment\n\n  Git does not store patches on a conceptual level, only snapshots. (At\nthe implementation level, Git uses \"patches\" for more optimized storage,\nbut that's not so important.)\n\n> What the heck is a branch? (Why does it have so many different\n> definitions? I feel like every time I come across \"branch\" in the man\n> pages, it means something different.)\n\n  Because it's hard to define. :-)\n\n  To make a cyclical definition, branch is the set of commits\nreferenced by a given head. Hmm, I'll have to think out some cute\nnon-confusing definition of branch, I'll follow up unless someone beats\nme to it.\n\n> More on branches: The wiki says that a group of commits linked\n> together form a DAG. Does that mean every fork/clone/branch-create\n> possibly doubles the number of branches. So if I fork and then\n> remerge, do I have two branches?\n> \n> A -> B -> D\n> A -> C -> D\n> \n> Would D be the head of this branch? If so, then heads do not uniquely\n> identify a branch?\n\n  Branch is a much looser concept than you seem to assume. Branch is\nreally just a fancy name for a 'head', so let's redefine 'head'. Let's\njust say for now that 'head' is a named commit reference.\n\n  This means that when you create a \"new branch\" 'foo' from branch\n'master', the _only_ thing you really did was to copy the commit\nreference 'master.\n\n> Is there a standard revision notation? (Where my definition of\n> \"revision\" is a tree snapshot. In SVN, it would be identified by a\n> number.) `cg-diff -r A..B` works fine if A and B are branches, but how\n> do I diff from an older revision to a newer revision? Can I diff\n> between two revisions which haven't shared the same parent since 2006?\n\n  You can diff between any two revisions. The ultimately \"standard\"\nnotation is to use the id of the revision (the long string of\nhexadecimal digits), but the syntax is quite rich - see SPECIFYING\nREVISIONS section of git-rev-parse(1).\n\n  If you specify a branch where revision is expected, it means that the\nlatest commit (revision) on the branch is used.\n\n> What about the master branch? Is there anything special about it? By\n> special I mean, do any of the git or cogito commands implicitly assume\n> that you are working with master? If git is truly decentralized, then\n> wouldn't master be on an equal footing with all other branches?\n\n  'master' is just the default name for the first branch in a\nrepository, but in theory you can name it any way you wish and use as\nmany branches as you want, all are equal.\n\n  When fetching from a remote repository, some commands might assume in\ncertain conditions that 'master' is the primary branch of the remote\nrepository, but I'm not sure about the details and in which cases does\nthis still hold true.\n\n> What is a merge? My understanding of merge comes from the SVN book,\n> where it was described as diff+apply. Diff takes 2 arguments, and\n> apply takes a 1 argument (if the patch is implicit). However, cg-merge\n> only appears to take one branch. (There again a use of the word\n> branch! Wouldn't commit or revision be a more accurate term?) Why does\n> cg-merge only take one argument? Even if I use the -b switch, I'm\n> still only up to two arguments. Where is the hidden argument?\n\n  The hidden argument is your current branch. So cg-merge x will merge\nthe branch 'x' to your current branch: symbolically, kind of\n\n\tbase=-b argument | base(HEAD, x)\n\tapply(HEAD, diff(base, x))\n\n  The word 'branch' is used in an attempt to make it all less confusing\n:-). But in fact, you can give cg-merge just id of a commit, it does not\nhave to be branch name.\n\n> Lastly, the most important question of all, which may answer many of\n> the questions above:\n> \n> Can you fill in the missing pieces, making corrections where\n> necessary? (recommend unispace font)\n> \n> Command     |   Reads               |   Writes\n> cg-fetch    | remote branch         | corresponding branch in local respository\n> cg-commit   | working copy          | HEAD\n> cg-update   | remote branch         | working copy AND HEAD\n> cg-merge    | branch & working copy | working copy\n> cg-diff     | arguments             | STDOUT\n> cg-push     |                       | remote branch (usually origin)\n> cg-pull     | remote branch         |\n> cg-restore  |                       |\n\n  Yes, mostly right. cg-merge calls cg-commit unless there are\nconflicts, so it should be \"working copy AND HEAD\" too. cg-push reads\nlocal branch (HEAD or -r argument). There is no cg-pull since people\ncoming from different VCSes have different ideas about what pull is; git\npull is equivalent to cg-update.\n\n> Perhaps the Reads column should be split into two, like ReadInfo and \n> ReadSafety.\n> ReadInfo would say which revision/branch/commit/object is being read for \n> actual\n> content, while ReadSafety is only read to make sure that nothing will be \n> lost\n> after running the command. (e.g., cg-update reads the working copy to make \n> sure\n> that you are not in a partial merge, but once it knows that it is safe, it\n> ignores the contents of working directory. I may have this totally wrong.)\n\n  It actually does some magic so that you can do a merge while having\nuncommitted changes in your working tree. ;-)\n\n> On cg-fetch, is the remote branch necessarily remote? Or can you fetch\n> from local\n> cg-switch-branches? What does \"corresponding branch in local\n> repository\" mean? Does cg-fetch touch your working copy?\n\n  Fetch means that a remote branch's content is transferred to the local\nrepository; furthermore, all the remote branches have their local\ncounterparts that \"reflect\" how the branch looked in the remote\nrepository at a particular point of time. So e.g. when you clone a\nrepository, the remote default branch is mirrored locally as branch\n'origin' - you can't switch to it (technically you could but that would\nbe very confusing), but you can merge it.\n\n> What is the difference between cg-restore and cg-seek?\n\n  cg-seek will temporarily bring your tree to a different commit to\nexplore the state back then, but you cannot make commits in this state;\nyour HEAD points to the seeked commit. On the other hand, cg-restore\nonly changes files in your working tree - it works on the individual\nfiles, does not touch HEAD and does not make the tree \"read-only\".\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nEver try. Ever fail. No matter. // Try again. Fail again. Fail better.\n\t\t-- Samuel Beckett\n"},{"id":"41624","messageId":"alpine.LFD.0.98.0705090856220.4062@woody.linux-foundation.org","threadId":"8055","inReplyTo":"92fdc3450705090830t64c8f5b9r4af277807dfe834d@mail.gmail.com","subject":"Re: svn user trying to recover from brain damage","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-05-09T16:57:12Z","receivedAt":"2007-05-09T16:57:12Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 9 May 2007, Joshua Ball wrote:\n> \n> What the heck do these terms mean?\n> \n> HEAD\n> HEAD REF\n\nThese are the same thing. HEAD is basically a special local branch, which \nusually (but not always) points to one of the local branches. I say \n\"usually\", because you *can* make it an independent branch in its own \nright, in which case you are using what is now called a \"detached\" HEAD.\n\nBut even when HEAD is \"detached\", and it's thus really an independent \nbranch in its own right, it's still special: it's the branch that your \ncurrent working tree is associated with.\n\nSo if you think of \"HEAD\" as just \"current branch\", you'll be in good \nshape.\n\n> working tree\n\nThis is just your files - both untracked (ie you may be building stuff in \nthe working tree) and tracked (ie the ones that git knows about).\n\nIt's *not* necessarily going to match the state that HEAD describes: HEAD \ndescribes the last *committed* state, while your working tree obviously \ncan have changes to the tracked files (along with files that aren't \ntracked at all), but the working tree state is certainly _associated_ with \nHEAD, in that HEAD would point to the most recent commit that the working \ntree is all about.\n\n> object\n\nThis is just an internal git term. It's how git stores all revision \nhistory information - as a set of objects in a content-addressable \nfilesystem. As a pure user, you generally never need to worry about this \nterm, although you might notice in the case you have corruption, and run \n\"git fsck\" and it starts talking about corrupt or missing objects.\n\n> branch\n\nA \"branch\" is just any \"tip of development\". It's *literally* defined by \nits name (which git doesn't care about, but you do), and the name of the \ntop-most commit (the SHA1) of that developmet series. That SHA1 is all \nthat git really cares about - the name is purely for your enjoyment and to \nclarify what the branch is about.\n\nGit can track an arbitrary number of branches, but your working tree would \nbe associated with just one of them, and HEAD points to that branch. The  \ndefault branch is called \"master\", but that doesn't really have any \nspecial meaning per se, and as mentioned, HEAD might even be a detached \nbranch and not associated with any \"real\" branch at all!\n\n> merge\n\nThat's the act of bringing in the contents of another branch (possibly \nfrom an external repository) into your current branch. If you merge from \nsomething external, you need to \"fetch\" that other branch first, and the \ncombination of \"fetch+merge\" is called a \"pull\".\n\nIt sounds like you may have never worked with branches before, in which \ncase you can just ignore *all* of this. Git will set up one branch for you \nat \"git init\" time (the \"master\" branch) and you don't actually ever have \nto use any more than that one branch, in which case you can literally \nignore everything about branches and merging.\n\n> master\n\nSee above: it's just the default name of the initial branch. It has no \nother meaning - git itself doesn't care about branch names at all, and \nit's literally nothing more than a \"default branch name\".\n\n> commit (as in the phrase \"bring the working tree to a given commit\")\n\nAny development series is just a series of \"commits\". They point to the \n\"parent\" commit(s) and can thus form a series (or more generally a DAG: \ndirected acyclic graph). \n\nSo a \"branch\" is really just a named pointer to a commit, and that commit \nwill in turn point to its parent commit, which will point to its parent \netc. Which is why I started by explaining a branch as a \"tip of \ndevelopment\", because you'd see a branch as the top-most commit that it \npoints to, and you'd normally *change* the branch by committing to it, \nwhich will create a new commit (and move the branch to point to it), and \nmake that new commit point to the old commit as its parent.\n\nOne of the best ways to visualize this is probably to just do\n\n - clone git itself if you haven't already\n\n\tgit clone git://git.kernel.org/pub/scm/git/git.git git\n\n - use \"gitk\" to see the commit history and see the branches as pointers \n   into that commit history. With \"--all -d\", it will show you all \n   branches, and the \"-d\" shows the commit history in date order, so while \n   it's a bit messier than the default cleaned-up format that tries to \n   show branches on their own, it's perhaps also a bit more instructive:\n\n\tgitk --all -d\n\nIn particular, you should see a commit that has both a green-boxed \n\"master\" pointer pointing to it, and a \"remotes/origin/master\" (colored in \na mixed brown/green box). Those are examples of branches: the \"master\" \nbranch is your local (and normally current) brach, while the \n\"remotes/origin/master\" thing is a so-called \"remote branch\", which means \nthat you cannot check it out, but you can see it and you can update it by \nfetching new versions from the remote.\n\n> Is there a difference between HEAD and the working tree?\n\nYes, see above.\n\n> Does HEAD change when I cg-switch/git-checkout?\n\nYes. But it switches by making it point to a different branch, while \nsomething like \"git reset\" will *also* potentially change HEAD, but do so \nby still staying on the same branch, but making that branch \"reset\" (aka \njump) to another point in history.\n\nSo you can literally change HEAD two fundamentally different ways:\n\n - by switching branches (which includes making HEAD be a detached branch \n   of its own)\n\n - by changing the state of the current branch (the most common form of \n   this is just \"git commit\" - it will update HEAD by creating a new \n   commit, but as mentioned, \"git reset\" can also do this by jumping \n   around in history, and that's how you'd undo work entirely, for \n   example).\n\n> What is an object? Is it a set of patches? A tree snapshot?\n\nAn object is the lowest-level of git information. It's an indivisible and \nunchanging \"thing\", that can potentially point to other objects. You \ncan kind of think of it as an \"inode\" in a UNIX filesystem, and like an \ninode, it can point to file data or be a directory (but unlike an inode, \nit's immutable by design, and it can also be a \"commit\" or a \"tag\" \nobject).\n\nSo internally, git does have \"tree snapshots\" (not patches - git is \n*purely* based on snapshotting states of the project), but they are not a \nsingle object, they are built up from \"tree objects\" that point to other \ntree objects or to \"blob objects\".\n\nAnd a commit is literally a \"commit object\" that points to the snapshot \n(the \"tree object\") that it's associated with, and the previous commits \n(the \"parents\") that build up the history.\n\n> What the heck is a branch? (Why does it have so many different\n> definitions? I feel like every time I come across \"branch\" in the man\n> pages, it means something different.)\n\nOk, hope I clarified that.\n\n> More on branches: The wiki says that a group of commits linked\n> together form a DAG. Does that mean every fork/clone/branch-create\n> possibly doubles the number of branches. So if I fork and then\n> remerge, do I have two branches?\n\nYes and no. When you do a clone, you do get your totally own set of \nbranches, but a branch is just a *pointer*. So it does _not_ duplicate \nhistory in any way, you do *not* get:\n\n> A -> B -> D\n> A -> C -> D\n\nBut instead you get\n\n\tA -> B -> C -> D\n\nas commits, and you now have a new pointer to D.\n\nSo creating a branch *literally* just creates a new pointer.\n\nIn fact, you can still create a new branch manually by doing\n\n\techo \"sha1-of-branch-goes-here\" > .git/refs/heads/my-new-branch\n\nand that is how the git scripts literally used to do it (well, slightly \nsimplified: verifying that the SHA1 is valid, and that the branch didn't \nalready exist).\n\nSo the branch really *is* just a named commit.\n\n> Would D be the head of this branch? If so, then heads do not uniquely\n> identify a branch?\n\nA branch uniquely identify a particular commit, but many branches can \npoint to the same commit (and the branches are considered \"identical\" when \nthey do that - you can have two different branches, but if they point to \nthe same thing they are identical in all respectcs except for naming).\n\n> Is there a standard revision notation? (Where my definition of\n> \"revision\" is a tree snapshot. In SVN, it would be identified by a\n> number.) `cg-diff -r A..B` works fine if A and B are branches, but how\n> do I diff from an older revision to a newer revision? Can I diff\n> between two revisions which haven't shared the same parent since 2006?\n\nThe \"standard\" revision notation is the SHA1 of the commit, but quite \nfrankly, you'd never use it.\n\nIf you have two branches named A and B, you'd generate the diff with\n\n\tgit diff A..B\n\nand it doesn't matter if they share a parent since yesterday, since five \nyears ago or whether they are related AT ALL. Git will happily diff \ntotally unrelated branches (if you imported two tar-balls independently, \nthey may not have any common history at all, but you may still want to \ndiff them if they are from the same project!)\n\n> What about the master branch? Is there anything special about it? By\n> special I mean, do any of the git or cogito commands implicitly assume\n> that you are working with master? If git is truly decentralized, then\n> wouldn't master be on an equal footing with all other branches?\n\nCorrect. \n\nThe only thing that is special about master is that it's the one that is \ncreated by \"git init\" (or \"git clone\", for that matter).\n\n> What is a merge? My understanding of merge comes from the SVN book,\n\nForget SVN merges. SVN cannot do merges (SVN also cannot really do \nbranches - what SVN calls branches is some abhorrent and stupid copy of a \nworking tree with copying of the limited notion of history that SVN \nknows about).\n\n> where it was described as diff+apply. Diff takes 2 arguments, and\n> apply takes a 1 argument (if the patch is implicit). However, cg-merge\n> only appears to take one branch. (There again a use of the word\n> branch! Wouldn't commit or revision be a more accurate term?)\n\n(You're likely better off using just \"raw git\" rather than cg these days, \nso I'll talk about \"git merge\").\n\nA \"git merge\" actually does have two branches: the current one, aka HEAD, \nand the one you want to merge _into_ the current one.\n\nSo when you do\n\n\tgit merge other-branch\n\nit will merge 'other-branch' into the current branch (HEAD).\n\nAnd no, it's not a \"diff+apply\" (although early and *very* broken versions \nof cg implemented the data part that way), it's a much more interesting \noperation that figures out the last common point from the history, and \ndoes a series of three-way merges (especially if there were *multiple* \nindependent common history points), and then records the set of parents \nin the result.\n\nThat, btw, is why SVN cannot do merges. It really *does* do a fancy \n\"diff+apply\" that probably involves three-way operations too, but since it \ndoesn't actually remember the resulting history, it cannot be considered a \n\"merge\". It didn't really merge the history - it just smushed the \n*contents* of two branches together, and then totally threw out all the \nreally important bits.\n\n> Lastly, the most important question of all, which may answer many of\n> the questions above:\n> \n> Can you fill in the missing pieces, making corrections where\n> necessary? (recommend unispace font)\n> \n> Command     |   Reads               |   Writes\n> cg-fetch    | remote branch         | corresponding branch in local respository\n> cg-commit   | working copy          | HEAD\n> cg-update   | remote branch         | working copy AND HEAD\n> cg-merge    | branch & working copy | working copy\n> cg-diff     | arguments             | STDOUT\n> cg-push     |                       | remote branch (usually origin)\n> cg-pull     | remote branch         |\n> cg-restore  |                       |\n\nI'll use the git names (which are generally the same)\n\n  Command\t| reads\t\t\t| writes\n  --------------+-----------------------+-----------\n  git fetch\t| remote branch(es)\t| local branch(es)\n  git commit\t| local data\t\t| HEAD\n  git pull\t| remote branch(es)\t| HEAD\n  git merge\t| local branch(es)\t| HEAD\n  git diff\t| local data\t\t|\n  git push\t| local branch(es)\t| remote branch(es)\n  git reset\t| ---\t\t\t| HEAD\n\nand everything that writes HEAD implicitly will always also update the \nworking tree too (with the obvious exception of \"git commit\" - since it's \nfilling in the HEAD with the current state, it's obviously not going to \nupdate the working tree).\n\nThe \"local data\" is really a combination of \"local branches, staging area \nand working tree\": neither \"git diff\" and \"git commit\" really work purely \non the working tree, they both will mix using the staging area, the \nworking tree, and pure branch information depending on exact flags.\n\nAnd note that most of the operations really can work on multiple branches \n(that's not true in cg). IOW, you can actually merge multiple branches in \none go (the end result is called an \"octopus merge\", because it looks cool \nand has many \"legs\" when you see the merge history in a bottom-to-top kind \nof thing like gitk).\n\n> On cg-fetch, is the remote branch necessarily remote? Or can you fetch\n> from local\n\nYou can always consider the local tree to be a remote one: just use \".\".\n\nSo\n\n\tgit merge other-branch\n\nis basically the same as\n\n\tgit pull . other-branch\n\n> cg-switch-branches? What does \"corresponding branch in local\n> repository\" mean? Does cg-fetch touch your working copy?\n\nConfusing cogito terminology.\n\nThe pure git stuff is actually clearer. And in git, you can specify what \nthe \"corresponding\" branch is for any local branch. For example, if you \njust do the \"git clone\" of the git repository, then assuming you have a \nrecent enough git, you can look into the \".git/config\" file of the result, \nand you should see something like this:\n\n\t[remote \"origin\"]\n\t\turl = master.kernel.org:/pub/scm/git/git.git\n\t\tfetch = +refs/heads/*:refs/remotes/origin/*\n\n\t[branch \"master\"]\n\t\tremote = origin\n\t\tmerge = refs/heads/master\n\nwhich describes a remote repository (\"origin\") and tells you what branches \nshould be fetched when you do a \"git fetch origin\", but it *also* \ndescribes the local branch \"master\", and says that when you do a \"git \npull\", it should merge the *remote* branch \"refs/heads/master\" from \n\"origin\".\n\n> What is the difference between cg-restore and cg-seek?\n\nDon't use them. Cogito confusion.\n\n\t\t\tLinus\n"},{"id":"41635","messageId":"20070509174307.GF23778@fieldses.org","threadId":"8055","inReplyTo":"92fdc3450705090830t64c8f5b9r4af277807dfe834d@mail.gmail.com","subject":"Re: svn user trying to recover from brain damage","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-05-09T17:43:07Z","receivedAt":"2007-05-09T17:43:07Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Wed, May 09, 2007 at 10:30:18AM -0500, Joshua Ball wrote:\n> 1. Tutorials for people brand new to version control, with just enough\n> information for them to \"obey the rules\", but completely empty of any\n> information that could help them exploit the real power of\n> decentralized version control.\n> 2. Technical documentation which assumes pre-obtained knowledge.\n\nWould you mind also trying\n\nhttp://www.kernel.org/pub/software/scm/git/docs/user-manual.html\n\nIt *tries* to fill that gap you're referring to, but you might find it\nhas some more gaps (which we'd like to hear about).\n\n> What the heck do these terms mean? The glossary on the Git wiki was\n> unhelpful (I'll explain later).\n\nHm.  I wonder how that and the glossary included in Documentation/ have\ndiverged?\n\n--b.\n"},{"id":"41654","messageId":"20070509201605.GC2982@efreet.light.src","threadId":"8055","inReplyTo":"20070509162259.GY4489@pasky.or.cz","subject":"Re: svn user trying to recover from brain damage","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2007-05-09T20:16:05Z","receivedAt":"2007-05-09T20:16:05Z","isPatch":false,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Wed, May 09, 2007 at 18:22:59 +0200, Petr Baudis wrote:\n> > What is a merge? My understanding of merge comes from the SVN book,\n> > where it was described as diff+apply. Diff takes 2 arguments, and\n> > apply takes a 1 argument (if the patch is implicit). However, cg-merge\n> > only appears to take one branch. (There again a use of the word\n> > branch! Wouldn't commit or revision be a more accurate term?) Why does\n> > cg-merge only take one argument? Even if I use the -b switch, I'm\n> > still only up to two arguments. Where is the hidden argument?\n> \n>   The hidden argument is your current branch. So cg-merge x will merge\n> the branch 'x' to your current branch: symbolically, kind of\n> \n> \tbase=-b argument | base(HEAD, x)\n> \tapply(HEAD, diff(base, x))\n> \n>   The word 'branch' is used in an attempt to make it all less confusing\n> :-). But in fact, you can give cg-merge just id of a commit, it does not\n> have to be branch name.\n\nI believe the important thing to explain here is the BASE, as that is really\nthe missing argument.\n\nSubversion Book describes merge as diff + apply. Diff takes 2 arguments - OLD\nand NEW, and apply takes 2 arguments - TARGET and result of diff. That gives\nus 3 arguments in total. 2 of them are passed to merge and the third is\ncurrent state of working tree.\n\nNow in git (and in any other version control tool), merge is still diff\n+ apply[1]. The TARGET is again implied by working tree. The argument to git\nmerge is the NEW. So where is the OLD missing?\n\nThe answer is simple: It is implied by the history! It is the most recent\ncommon ancestor of the NEW and TARGET, or in other words latest revision that\nis predecessor of both revisions being merged.\n\nAn important distinction between subversion and git here is, that in git BOTH\nNEW and TARGET are considered parents of the new commit created by merge.\nThis means that repeated merges just work without need to look in the logs or\nanywhere for what changes need to be applied.\n\nThe OLD, NEW and TARGET argument names are derived from diff/patch\nterminology. More common (also in git) is to call them BASE, REMOTE and LOCAL\nrespectively.\n\nIt might be interesting to note, that merging is *symetrical* operation.\nSwapping the LOCAL and REMOTE will give the same result, except for order in\nwhich parents are recorded in the commit object and the order in which\nconflicted sections are written out in case of conflict.\n\nThis is property is not in any way special to git. It is fundamental property\nof patches. Git just cares very little about the order.\n\n[1] The 3-way merge algorithm is not diff+apply internally, but is\n    equivalent to diff+apply with full context (whole file is kept), except\n    for way it marks conflicts.\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"41844","messageId":"f228t6$qnq$1@sea.gmane.org","threadId":"8055","inReplyTo":"92fdc3450705090830t64c8f5b9r4af277807dfe834d@mail.gmail.com","subject":"Re: svn user trying to recover from brain damage","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-11T17:29:31Z","receivedAt":"2007-05-11T17:29:31Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"[Cc: Joshua Ball <sciolizer@gmail.com>, git@vger.kernel.org]\n\nJoshua Ball wrote:\n\n> What the heck do these terms mean? The glossary on the Git wiki was\n> unhelpful (I'll explain later).\n\nGlossary at GitWiki, http://git.or.cz/gitwiki/GitGlossary is\nwikification of \"GIT Glossary\" from Documentation/glossary.txt\ndistributed with git-core and installed usually under\n\n  /usr/share/doc/git-core-<version>/glossary.html\n\nbut also available at\n\n  http://www.kernel.org/pub/software/scm/git/doc/glossary.html\n\nThis wiki page was created for GitWiki to be self contained\n(to be able to reference to anchor in GitGlossary when referring\nto some term which needs explanation), and also to be able to add\nsome links to wiki pages in wikified GitGlossary. This wiki page\nis probably a bit outdated.\n\n> head\n> head ref\n> working tree\n> object\n> branch\n> merge\n> master\n> commit (as in the phrase \"bring the working tree to a given commit\")\n> \n> While the Git wiki does in fact define all of these, it doesn't answer\n> any of my questions about those terms:\n[cut]\n\nI hope that the following mini-tutorial with some explanations would\nhelp you understand those terms, and clean some SVN misconceptions.\n\n\nIn git history itself is separated from the references to it; when cloning\nor fetching from other repository, you get and append missing parts of\nhistory, but the refs on the remote and on local side does not need to\nhave the same names. In the ascii-art graphs of history objects which\nare in \"object database\" (in history) are on the left, and references\nto history are on the right.\n\n /------ object database -----------\\  /------- refs --------\\\n\nLet's start with the following history (the following repository\nstructure)\n\n   A <-- B <-- C <-- D <----------------- master <------- HEAD\n\n\n$ git branch branchA\n(does not change working directory)\n\n   A <-- B <-- C <-- D <----------------- master <------- HEAD\n                      \\\n                       \\\n                        \\--------------- branchA\n\nBranching does not create copy of revisions so far (even if it is\ncheap copy like in the case of Subversion). You can always find\nthe place where branches diverge; it is recorded in repository.\n\"git merge-base master branchA\" returns [id of] revision D.\n\nCreating a branch is just creating a pointer (reference) to some\ncommit. Head ref, or just a head is this pointer, e.g. 'branchA'\n(it resides in  $GIT_DIR/refs/heads/branchA). Commit D is often\ncalled branch tip. Branch as a non-cyclical graph of revisions\nis, in the case of 'branchA', branch history of commit D including\nthis commit, i.e. A<--B<--C<--D DAG.\n\nHEAD (case sensitive, all uppercase) is current branch, usuually\npointer to some other branch.\n\n\n$ git checkout branchA\n(changes working directory, updates HEAD)\n\n   A <-- B <-- C <-- D <----------------- master      /- HEAD\n                      \\                              /\n                       \\                            /\n                        \\--------------- branchA <-/\n\nThose two above steps can be combined to single command\n$ git checkout -b branchA\n\n\n$ edit; edit; ... (changes working directory)\n$ git commit -a\n(this creates new commit object E, updates branchA ref, i.e.\n ref pointed by HEAD, aka. current branch [head])\n\n   A <-- B <-- C <-- D <----------------- master       /- HEAD\n                      \\                               /\n                       \\                             /\n                        \\- E <----------- branchA <-/\n\nCommitting (commit as verb) creates commit object E (commit as noun),\nand advances branch head to the newly created commit.\n\n\n$ git checkout master\n$ edit; edit; ...\n$ git commit -a\n\n   A <-- B <-- C <-- D <-- F <------------ master <----- HEAD\n                      \\\n                       \\\n                        \\- E <----------- branchA\n\nNote that \"git commit\" advances current branch head / tip of current\nbranch, i.e. branch pointed to by HEAD reference.\n\n\n$ git merge branchA\nThis does equivalent of doing \"diff3 -E F D E\", i.e. 3-way merge on\nfile level, or \"diff3 -E HEAD $(git merge-base HEAD branchA) branchA\"\n\n   A <-- B <-- C <-- D <-- F <-- G <------ master <----- HEAD\n                      \\        /\n                       \\      /\n                        \\- E- <---------- branchA\n\nMerging (merge as verb) creates merge commit [object] G (merge as noun).\nCommit object G has commits G and E as parents (more than one parent).\nThe information that G is result of merge is recorded in commit\n[object] G.\n\n\nIf you have noticed that you want to discard the merge, for example\nyou don't want to merge yet, i.e. you want to return to state before\nmerge you can do:\n\n$ git reset --hard ORIG_HEAD\n(updates current branch, *does not* update HEAD as a ref,\n contrary to git-checkout)\n\n                           |------\\\n                           v       \\\n   A <-- B <-- C <-- D <-- F <-- G  \\----- master <----- HEAD\n                      \\        /\n                       \\      /\n                        \\- E- <---------- branchA\n\n\nAssume situation at the graph before\n\n$ git checkout branchA\n$ edit; edit; ...\n$ git commit -a\n(creates commit H)\n$ git checkout master\n$ git merge branchA\nThis time, because merge is recorded as such, the merge base between\n'master' branch (branch we merge into) and 'branchA' (branch being\nmerged) is commit E. Git knows that it has to merge only changes\naccumulated since last merge.\n\n   A <-- B <-- C <-- D <-- F <-- G <- J <- master <----- HEAD\n                      \\        /     /\n                       \\      /     /\n                        \\- E-<-- H <------ branchA\n\n \n> In the words of Dijkstra, \"Since breaking out of bad habits, rather\n> than acquiring new ones, is the toughest part of learning, we must\n> expect from that system permanent mental damage for most ... exposed\n> to it.\"\n> \n> May you lead me to a quick recovery. Hail to decentralized version control.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"}]}