{"thread":{"id":"6207","subject":"Re: [DRAFT] Branching and merging with git","startedAt":"2006-11-16T22:17:01Z","lastAt":"2007-01-10T04:15:17Z","messageCount":37,"participants":["Theodore Tso","Junio C Hamano","linux@horizon.com","J. Bruce Fields","Jakub Narebski","Guilhem Bonnefille","David Kågedal","Andreas Ericsson","Nguyen Thai Ngoc Duy","Sean","Petr Baudis","Chris Riddoch","Marko Macek"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"295842","messageId":"20061116221701.4499.qmail@science.horizon.com","threadId":"6207","inReplyTo":null,"subject":"[DRAFT] Branching and merging with git","fromName":"","fromEmail":"linux@horizon.com","sentAt":"2006-11-16T22:17:01Z","receivedAt":"2006-11-16T22:17:01Z","isPatch":false,"sender":{"key":"linux@horizon.com","avatar":null},"body":"I know it took me a while to get used to playing with branches, and I\nstill get nervous when doing something creative.  So I've been trying\nto get more comfortable, and wrote the following to document what I've\nlearned.\n\nIt's a first draft - I just finished writing it, so there are probably\nsome glaring errors - but I thought it might be of interest anyway.\n\n\n* Branching and merging in git\n\nIn CVS, branches are difficult and awkward to use, and generally\nconsidered an advanced technique.  Many people use CVS for a long time\nwithout departing from the trunk.\n\nGit is very different.  Branching and merging are central to effective use\nof git, and if you aren't comfortable with them, you won't be comfortable\nwith git.  In particular, they are required to share work with other\npeople.\n\nThe only things that are a bit confusing are some of the names.\nIn particular, at least when beginning:\n- You create new branches with \"git checkout -b\".\n  \"git branch\" should only be used to list and delete branches.\n- You share work with \"git fetch\" and \"git push\".  These are opposites.\n- You merge with \"git pull\", not \"git merge\".  \"git pull\" can\n  also do a \"git fetch\", but that's optional.  What's not optional\n  is the merge.\n\n\n* A brief digression on command names.\n\nOriginally, all git commands were named \"git-foo\".  When there got to\nbe over a hundred, people started complaining about the clutter in\n/usr/bin.  After some discussion, the following solution was reached:\n\n- It's now possible to place all of the git-foo commands into a separate\n  directory.  (Despite the complaints, not too many people are doing it\n  yet.)\n- One option for git users is to add that directory to their $PATH.\n- Another is provided by a wrapper called just \"git\".  It's intended to\n  live in a public directory like /usr/bin, and knows the location of\n  the separate directory.  When you type \"git foo\", it finds and executes\n  \"git-foo\".\n- Some simple commands are built into the git wrapper.  When you type\n  \"git add\", it just does it internally.  (On the git mailing list,\n  you will see patches like \"make git diff a builtin\"; this is what\n  they're talking about.)\n- For compatibility, for each builtin, there is a \"git-add\" file,\n  which is just a link to the \"git\" wrapper.  It looks at the name it\n  was invoked as to figure out what it should do.\n\nThe one confusing thing is that, although people usually type \"git foo\"\nin examples, they're interchangeable in practice.  I go back and forth\nfor no good reason.  The main caveat is that to get the man page, you\nstill need to type \"man git-foo\".  Fortunately, there are two other ways\nto get the man page:\n\n\t1) \"git help foo\"\n\t2) \"git foo --help\"\n\nGit doesn't have a specialized built-in help system; it just shows you\nthe man pages.\n\nOne outstanding problem with git's man pages is that often the most detail\nis in the command page that was written first, not the user-friendly\none that you should use.  For example, there are a number of special\ncases of the \"git diff\" command that were written first, and the man\npages for these commands (git-diff-index, git-diff-files, git-diff-tree,\nand git-diff-stages) are considerably more informative than the page for\nplain git-diff, even though that's the command that you should use 99%\nof the time.\n\n* Git's representation of history\n\nAs you recall from Git 101, there are exactly four kinds of objects in\nGit's object database.  All of them have globally unique 40-character hex\nnames made by hashing their type and contents.  Blob objects record file\ncontents; they contain bytes.  Tree objects record directory contents;\nthey contain file names, permissions, and the associated tree or blob\nobject names.  Tag objects are shareable pointers to other objects;\nthey're generally used to store a digital signature.\n\nAnd then, we come to commit objects.  Every commit points to (contains\nthe name of) an associated tree object which records the state of the\nsource code at the time of the commit, and some descriptive data (time,\nauthor, committer, commit comment) about the commit.\n\nAnd most importantly, it contains a list of \"parent commits\", older\ncommits from which this one is derived.  These pointers are what produce\nthe history graph.\n\nTypically only one commit (the initial commit) has zero parents.  It's\npossible to have more than one such commit (if you merge two projects\nwith different history), but that's unusual.\n\nMany commits have exactly one parent.  These are made by a normal commit\nafter editing.  From a branching and merging point of view, they're not\ntoo exciting.\n\nAnd then there are commits which have multiple parents.  Two is most\ncommon, but git allows many more.  (There's a limit of sixteen in the\nsource code, and the most anyone's ever used in real life is 12, and\nthat was generally regarded as overdoing it.  Google on \"doedecapus\"\nfor discussion of it.)\n\nFinally, there are references, stored in the .git/refs directory.\nThese are the human-readable names associated with commits, and the\n\"root set\" from which all other commits should be reachable.\n\nThese references are generally divided into two types, although\nthere is no fundamental difference:\n- Tags are references that are intended to be immutable.\n  The \"v1.2\" tag is a historical record.  A tag may point to\n  a tag object (which will hold a signature), or just to a commit\n  directly.  The latter isn't cryptographically authenticated, but\n  works just fine for everyday use.\n- Heads are references that are intended to be updated.  \"Head\"\n  is actually synonymous with \"branch\", although one emphasizes the\n  tip more, while the other directs your attention to the entire\n  path that got there.\nEither way, they're just a 41-byte file that contains a 40-byte hex\nobject ID, plus a newline.  Tags are stored in .git/refs/tags, and heads\nare stored in .git/refs/heads.  Creating a new branch is literally just\npicking a file name and writing the ID of an existing commit into it.\n\nThe git programs enforce the immutability of tags, but that's a safety\nfeature, not something fundamental.  You can rename a tag to the heads\ndirectory and go wild.\n\nThe only limit on branches is clutter.  A number of git commands have\nways to operate on \"all heads\", and if you have too many, it can get\nannoying.  If you're not using a branch, either delete it, or move it\nsomewhere (like the tags directory) where it won't clutter up the list of\n\"currently active heads\".\n\n(Note that CVS doesn't have this all-heads default, so people tend to\nuse longer branch names and keep them around after they've been merged\ninto the trunk.  Old CVS repositories converted to git generally need\nan old-branch cleanup.)\n\nAnother thing that's worth mentioning is that head and tag names can\ncontain slashes; i.e. you're allowed to make subdirectories in the\n.git/refs/heads and .git/refs/tags directories.  See the name page\nfor \"git-check-ref-format\" for full details of legal names.\n\n\n* Naming revisions\n\nCVS encourages you to tag like crazy, because the only other way to\nfind a given revision is by date.  Git makes it a lot easier, so most\nrevisions don't need names.\n\nYou can find a full description in the git-rev-parse man page, but here's\na summary.\n\nFirst of all, every commit has a globally unique name, its 40-digit hex\nobject ID.  It's a bit long and awkward, but always works.  This is useful\nfor talking about a specific commit on a mailing list.  You can abbreviate\nit to a unique prefix; most people find about 8 digits sufficient.\n\n(Subversion is easier yet, because it assigns a sequential number to each\ncommit.  However, that isn't possible in a distributed system like git.)\n\nSecond, you can refer to a head or tag name.  Git looks in the\nfollowing places, in order, for a head:\n\t1) .git\n\t2) .git/refs\n\t3) .git/refs/heads\n\t4) .git/refs/tags\n\nYou should avoid having e.g. a head and a tag with the same name, but\nif you do, you can specify one or the other with heads/foo and tags/foo.\n\nThird, you can specify a commit relative to another.  The simplest\none is \"the parent\", specified by appending ^ to a name.  E.g.  HEAD^\nor deadbeef^.  If there are multiple parents, then ^ is the same as ^1,\nand the others are ^2, ^3, etc.\n\nSo the last few commits you've made are HEAD, HEAD^, HEAD^^, HEAD^^^, etc.\nAfter a while, counting carets becomes annoying, so you can abbreviate\n^^^^ as ~4.  Note that this only lets you specify the first parent.\nIf you want to follow a side branch, you have to specify something like\n\"master~305^2~22\".\n\n\n* Converting between names\n\nGit has two helpers (programs designed mainly for use in shell scripts)\nto convert between global object IDs and human-readable names.\n\nThe first is git-rev-parse.  This is a general git shell script helper,\nwhich validates the command line and converts object names to absolute\nobject IDs.  Its man page has a detailed description of the object\nname syntax.\n\nThe second is git-name-rev, which converts the other way around.  It's\nparticularly useful for seeing which tags a given commit falls between.\n\n\n* Working with branches, the trivial cases.\n\nBy convention, the local \"trunk\" of git development is called \"master\".\nThis is just the name of the branch it creates when you start an empty\nrepository.  You can delete it if you don't like the name.\n\nIf you create your repository by cloning someone else's repository, the\nremote \"master\" branch is copied to a local branch named \"origin\".  You\nget your own \"master\" branch which is not tied to the remote repository.\n\nThere is always a current head, known as HEAD.  (This is actually a\nsymbolic link, .git/HEAD, to a file like refs/heads/master.)  Git requires\nthat this always point to the refs/heads directory.\n\n\tMinor technical details:\n\t1) HEAD used to be a Unix symlink, and can still be though of that\n\t   way, but for Microsoft support, this is now what's called a\n\t   \"symbolic reference\" or symref, and is a plain file containing\n\t   \"ref: refs/heads/master\".  Git treats it just like a symlink.\n\t   There's a git-update-ref helper which writes these.\n\t2) While HEAD must point to refs/heads, it's legal for it to\n\t   point to a file that doesn't exist.\tThis is what happens\n\t   before the first commit in a brand new repository.\n\nWhen you do \"git commit\", a new commit object is created with the old\nHEAD as a parent, and the new commit is written to the current head\n(pointed to by HEAD).\n\n\n* The three uses of \"git checkout\"\n\nGit checkout can do three separate things:\n\n1) Change to a new head\n\n\tgit checkout [-f|-m] <branch>\n   This makes <branch> the new HEAD, and copies its state to the index\n   and the working directory.\n\n   If a file has unsaved changes in the working directory, this tries\n   to preserve them.  This is a simple attempt, and requires that the\n   modified files(s) are not altered between the old and new HEADs.\n   In that case, the version in the working directory is left untouched.\n\n   A more aggressive option is -m, which will try to do a three-way\n   (intra-file) merge.  This can fail, leaving unmerged files in the\n   index.\n\n   An alternative is to use -f, which will overwrite any unsaved changes\n   in the working directory.  This option can be used with no <branch>\n   specified (defaults to HEAD) to undo local edits.\n\n2) Revert changes to a small number of files.\n\n\tgit checkout [<revision>] [--] <paths>\n   will copy the version of the <paths> from the index to the working\n   directory.  If a <revision> is given, the index for those paths will\n   be updated from the given revision before copying from the index to\n   the working tree.\n\n   Unlike the version with no <paths> specified, this does NOT update\n   HEAD, even if <paths> is \".\".\n\n3) Create a branch.\n\n\tgit checkout [-f|-m] -b <branch> [revision]\n   will create, and switch to, a new branch with the given name.\n   This is equivalent to\n\tgit branch <branch> [<revision>]\n\tgit checkout [-f|-m] <branch>\n   If <revision> is omitted, it defaults to the current HEAD, in which\n   case no working directory files are altered.\n\n   This is the usual way that one checks out a revision that does not\n   have an existing head pointing to it.\n\n\n* Deleting branches\n\n\"git branch -d <head>\" is safe.  It deletes the given <head>, but first\nit checks that the commit is reachable some other way.  That is, you\nmerged the branch in somewhere, or you never did any edits on that branch.\n\nIt's a good idea to create a \"topic branch\" when you're working on\nanything bigger than a one-liner, but it's also a good idea to delete\nthem when you're done.  It's still there in the history.\n\n* Doing rude things to heads: git reset\n\nIf you need to overwrite the current HEAD for some reason, the tool to\ndo it with is \"git reset\".  There are three levels of reset:\n\ngit reset --soft <head>\n\tThis overwrites the current HEAD with the contents of <head>.\n\tIf you omit <head>, it defaults to HEAD, so this does nothing.\ngit reset [<head>]\ngit reset --mixed [<head>]\n\tThese overwrite the current HEAD, and copy it to the index,\n\tundoing any git-update-index commands you may have executed.\n\tIf you omit <head>, it default to HEAD, so there is no change\n\tto the current branch, but all index changes are undone.\ngit reset --hard [<head>]\n\tThis does everything mentioned above, and updates the\n\tworking directory.  This throws away all of your in-progress\n\tedits and gets you a clean copy.  This is also commonly\n\tused without an explicit <head>, in which case the current\n\tHEAD is used.\n\n* Using git-reset to fix mistakes\n\n\"Oh, no!  I didn't mean to commit *that*!  How do I undo it?\"\n\nIf you just want to undo a commit, then you can use \"git reset HEAD^\"\nto return the current HEAD to the previous version.  If you want to leave\nthe commit in the index (this only applies to you if you are familiar with\nusing the index; see below), then you can use \"git reset --soft HEAD^\".\n\nAnd if you want to blow away every record of the changes you made,\nyou can use \"git reset --hard HEAD^\"\n\nIf you just want a stupid trivial mistake and want to replace the most\nrecent commit with a corrected one, \"git commit --amend\" is your friend.\nIt makes a new commit with HEAD^ rather than HEAD as its ancestor.\n\n* Fixing mistakes without git-reset\n\ngit-reset has the problem that it doesn't preserve hacking in progress\nin the working directory.  It can leave the working directory alone\n(making everything a \"hack in progress\"), but it can't merge changes\nlike git checkout.\n\nSo, suppose you've been trying something that should have been simple, and\nmade three commits before realizing that the problem is harder than you\nthought and you want your work so far to be on a new branch of its own;\ncommitting them on the current HEAD (I'll call it \"old\") was a mistake.\n\nYou don't want to erase anything, just rename it.  Make \"new\" a copy of\nthe current \"old\" and move old back to HEAD^^^ (three commits ago).\n\nWhile there are ways to do that using git-reset, but far better is\nto use \"git branch -f\":\n\n\tgit checkout -b new\n\t\tCreate (and switch to) the \"new\" branch.\n\tgit branch -f old HEAD^^^\n\t\tForcibly move \"old\" back three versions.\n\t\t(You could also use old~3 or new^^^ or any synonymous name.)\n\nYou can use a similar trick to rename a branch.  If it's the current\nHEAD, then:\n\n\tgit checkout -b newname\n\tgit branch -d oldname\n\nand if it's not, then\n\n\tgit branch newname oldname\n\tgit branch -d oldname\n\nAn alternative in the latter case is to just use mv on the raw\n.git/refs/heads/oldname file.\n\n\n* How do I check out an old version?\n\nA very common beginning question is how to check out an old version.\nSay you need to compile an old release for test purposes.  \"git checkout\nv1.2\" gives a funny error message.  What's going on?\n\nWell, \"git checkout\" makes the current HEAD point to the head that\nyou specify.  And, as previously mentioned, git requires that it point\nto something in the .git/refs/heads directory.  So you can't do that.\n\nIf you're busy doing things in your working directory, and don't want to\noverwrite your work with an old version, then you can get a snapshot with\nthe (old) git-tar-tree or (new) git-archive commands.  These produce a\ntar file (git-archive can also produce a zip file) which is a snapshot\nof any version you like.  You can then unpack this file in a different\ndirectory and build it.\n\nHowever, if you haven't got any edits in progress, and want to check out\nthe old version into your working directory, just create a temp branch!\n\n\tgit checkout -b temp v1.2\n\nWill do what you want.  This will also do what you want if you have a\nlocal edit (like the \"#define DEBUG 1\" mentioned above) that you want\nto preserve while working on the old version.\n\nYou'll see this in use if you ever use the (highly recommended) git-bisect\ntool.  It creates a branch called \"bisect\" for the duration of the bisect.\n\n(Yes, I have to confess, I sometimes wish that git would enforce the\n\"HEAD must point to .git/refs/heads\" rule when committing (checking in)\nrather than when checking out, but that's the way git has grown up.)\n\n\nNote that if you want *exactly* an old version, with no local hacks,\nmake sure there are none (with \"git status\") when doing this.  It's more\nconvenient if you do it before the checkout, but you'll get the same\nanswer if you ask afterwards.\n\n\nNow, what about the complex case: you have local hacks that you\nwant to keep, but not have polluting the old version?\n\nWell, one way of the other, you'll have to commit it.  If you don't mind\ncommitting your changes to the current branch (\"git commit -a\"), do that.\n\nIf they're not ready to commit, you can commit them anyway, and back\nthem out when you're done:\n\n\tgit commit -a -m \"Temp commit\"\n\tgit checkout -b temp v1.2\n\tmake ; make test ; whatever\n\tgit checkout master\n\tgit branch -d temp\n\tgit reset HEAD^\n\nThis leaves both the working directory and the master head in the states\nthey were in at the beginning.\n\nIf you don't like committing to the master branch, you can make a new one.\nIn this example, it's \"work in progress\", a.k.a. \"wip\":\n\n\tgit checkout -b wip\n\tgit commit -a -m \"Temp commit\"\n\tgit checkout -b temp v1.2\n\tmake ; make test ; whatever\n\tgit checkout wip\n\tgit branch -d temp\n\tgit reset master\n\tgit checkout master\t# Won't change working directory\n\tgit branch -d wip\n\n\n* Examining history: git-log and git-rev-list\n\nIn another example of docs being better on the first command written,\nthe all-purpose utility for examining history is \"git log\", but all of\nthe examples of clever ways to use it are in the git-rev-list man page.\nAnd git-log also has most of git-diff's options.\n\nOther utilities, notably the gitk and qgit GUIs, also use the git-rev-list\ncommand-line options, so it's well worth learning them.\n\n\ngit-rev-list gives you a filtered subset of the repository history.\nThere are two basic ways that you can do the filtering:\n\n1) By ancestry.  You specify a set of commits to include all the\n   ancestors of, and another set to exclude all the ancestors of.\n   (For this purpose, a commit is considered an ancestor of itself.)\n\n   So if you want to see all commits between v1.1 and v1.2, you\n   can specify\n\n   \tgit log ^v1.1 v1.2\n   or, with a more convenient syntax\n   \tgit log v1.1..v1.2\n\n  However, there are times when you want to specify something more\n  complex.  For example, if a big branch that had been in progress since\n  v1.0.7 was merged between v1.1 and v1.2, but you don't want to see it,\n  you could specify any of:\n\n   \tgit log v1.2 ^v1.1 ^bigbranch\n   \tgit log ^bigbranch v1.1..v1.2\n\tgit log ^v1.1 bigbranch..v1.2\n\n  They're all equivalent.  Another special syntax that's sometimes\n  handy is\n\n\tgit log branch1...branch2\n\n   Note the three dots.  This generates the symmetric difference between\n   the two; basically it's a diff between the commits that went into\n   each of them.\n\n   \"git log\" by default pipes its output through less(1), and generates\n   its output from newest to oldest on the fly, so there's no great\n   speed penalty to not specifying a starting place.  It'll generate a\n   few screen fulls more than you look at, but not waste any more effort\n   than that.\n\n2) By path name.  This is a feature which appears to be unique to git.\n   If you give git-rev-list (or git-log, or gitk, or qgit) a list of\n   pathname prefixes, it will list only commits which touch those\n   paths. So \"git log drivers/scsi include/scsi\" will list only\n   commits which alters a file whose name begins with drivers/scsi\n   or include/scsi.\n\n   (If there's any possible ambiguity between a path name and a commit\n   name, git-rev-list will refuse to proceed.  You can resolve it by\n   including \"--\" on the command line.  Everything before that is a\n   commit name; everything after is a path.)\n\n   This filter is in addition to the ancestry filter.  It's also rather\n   clever about omitting unnecessary detail.  In particular, if there's\n   a side branch which does touch drivers/scsi, then the entire branch,\n   and the merge at the end, will be removed from the log.\n\nYou can additionally limit the commits to a certain number, or by date,\nauthor, committer, and so on.\n\nBy default, \"git log\" only shows the commit messages, so it's important to\nwrite good ones.  Other tools compress commit messages down to\nthe first line, so try to make that as informative as possible.\n\n\n* History diagrams\n\nWhen talking about various situations involving multiple branches,\npeople often find it handy to draw pictures.  Gitk draws nice pictures\nvertically, but for e-mail, ASCII art drawn horizontally is often easier.\nCommits are shown as \"o\", and the links between them with lines drawn with\n- / and \\.  Time goes left to right, and heads may be labelled with names.\n\nFor example:\n\n         o--o--o <-- Branch A\n        /\n o--o--o <-- master\n        \\\n         o--o--o <-- Branch B\n\nIf someone needs to talk about a particular commit, the character \"o\"\nmay be replaced with another letter or number.\n\n\n* Trivial merges: fast-forward and already up-to-date.\n\nThere are two kinds of merge that are particularly simple, and you will\nencounter them in git a great deal.  They are mirror images.\n\nSuppose that you are working on branch A and merge in branch B, but no\nwork has been done to branch B since the last time you merged, or since\nyou spawned branch A from it.  That is, the history looks like\n\n\n o--o--o--o <-- B\n           \\\n\t    o--o--o <-- A\nor\n o--o--o--o--o--o <-- B\n           \\     \\\n\t    o--o--o--o--o <-- A\n\nIf you then merge B into A, A is described as \"already up to date\".\nIt is already a strict superset of B, and the merge does nothing.\n\nIn particular, git will not create a dummy commit to record the fact that\na merge was done.  It turns out that are a number of bad things that would\nhappen if you did this, but for now, I'll just say that git doesn't do it.\n\n\nNow, the opposite scenario is the \"fast-forward\" merge.  Suppose you\nmerge A into B.  Again, A is a strict superset of B.\n\nIn this case, git will simply change the head B to point to the same\ncommit as A and say that it did a \"fast-forward\" merge.  Again, no commit\nobject is created to reflect this fact.\n\nThe effect is to unclutter the git history.  If I create a topic branch to\nwork on a feature, do some hacking, and then merge the result back into\nthe (untouched!) master, the history will look just like I did all the\nwork on the master directly.  If I then delete the topic branch (because\nI'm done using it), the repository state is truly indistinguishable.\n\nWhile the topic branch existed, you could have done something to the\nmaster branch, in which case the final merge would have been non-trivial,\nbut if that didn't happen, git produces a simple, easy-to-follow linear\nhistory.\n\nSome people used to heavyweight branches find this confusing; they\nthink a merge is a big deal and it should be memorialized, but there\nare actually excellent reasons for doing this.\n\nThe most important one is that a fit of merging back and forth will\neventually end.  Suppose that branches A and B are maintained by separate\ndevelopers who like to track each other's work closely.\n\nIf the fast-forward case did create a commit, then merging A into B\nwould produce\n\n o--o--o--o---------o <-- B\n           \\       /\n\t    o--o--o <-- A\nthen merging B into A would produce:\n o--o--o--o---------o <-- B\n           \\       / \\\n\t    o--o--o---o <-- A\n\nand further merges would produce more and more dummy commits, all without\never reaching a steady state, and without making it obvious that the\ntwo heads are actually identical.\n\nSince history lasts forever, cluttering it up with unimportant stuff is a\nburden to all future users, and not a good idea.  Allowing the merge of a\nbranch to be seamless in the simple case encourages lightweight branches.\nIf you _might_ need a separate branch, create it.  If it turned out that\nyou didn't, it won't make a difference.\n\n\n* Exchanging work with other repositories\n\nThe basic tools for exchanging work with other repositories are \"git\nfetch\" and \"git push\".  The fact that \"git pull\" is not the opposite of\n\"git push\" is often confusing to beginners (it's a superset of git fetch),\nbut that's the terminology that has grown up.\n\nThe unit of sharing in git is the branch.  If you've used branches in\nCVS, you'll be familiar with using \"CVS update\" to pull changes from your\n\"current branch\" in the repository into your working directory.\n\nIn Git, you don't pull into the working directory, but rather into a\ntracking branch.  You set up a branch in your repository which will be\na copy of the branch in the remote repository.  For example, if you use\n\"git clone\", then the remote \"master\" branch is tracked by the local\n\"origin\" branch.\n\nThen, when you do a \"git fetch\", git fetches all of the new commits\nand sets the origin head to point to the newly fetched head of the\nremote branch.\n\nBy default, git checks that this is a trivial fast-forward merge, that\nis not throwing away history.  If it finds something like:\n\no--o--o--o--o--o <-- remote master\n       \\\n        o <-- Local origin\n\nIt will complain and abort the fetch.  This is usually a warning that\nsomething has gone wrong - in particular, you forgot that this was\nsupposed to be a tracking branch and committed some work to it - and it\naborts before throwing your work away.\n\nHowever, sometimes the remote git user will have a branch name that they\ndelete and re-create frequently.  There are plenty of reasons to do this.\nThe most common is doing a \"test merge\" between various branches in\nprogress.  They're all unfinished, so the developer of branch A doesn't\nwant to merge in all the new bugs in branch B, but a tester might want\nto create a merged version with both sets of bugs for testing.\n\nThe merged version is not intended to be a permanent part of history -\nit'll get deleted after the test - but it can still be useful to have\na draft copy.\n\nIn this case, you can mark the source branch with a leading \"+\", to\ndisable this sanity check.  (See the git-fetch man page for details.)\n\nNote that in this case, you should specifically avoid merging from such\na branch into any non-test branches of your own.  It is, as mentioned,\nnot intended to be a permanent part of history, so don't make it part\nof your permanent history.  (You still might want to test-merge it with\nyour work in progress, of course.)\n\nThe fact that you should know to treat such branches specially is why\ngit doesn't try to automatically cope with them.\n\n\n* Alternate branch naming\n\nThe original git scheme mixes tracking branches with all the other heads.\nThis requires that you remember which branches are tracking branches and\nwhich aren't.  Hopefully, you remember what all your branches are for,\nbut if you track a lot of remote repositories, you might not remember\nwhat every remote branch is for and what you called it locally.\n\n* Remotes files\n\nYou can specify what to fetch on the git-fetch command line.  However,\nif you intend to monitor another repository on an ongoing basis,\nit's generally easier to set up a short-cut by placing the options in\n.git/remotes/<name>.\n\nThe syntax is explained in the git-fetch man page.  When this is st\nup, \"git fetch <name>\" will retrieve all the branches listed in the\n.git/remotes/<name> file.  The ability to fetch multiple branches at\nonce (such as release, beta, and development) is an advantage of using\na remotes file.\n\nYou can also create the remotes file \"origin\" (not necessarily any\nrelation to the branch named \"origin\"), which is the default for\ngit-fetch.  If you have a single primary \"upstream\" repository that\nyou sync to, place it in the origin remotes file, and you can just type\n\"git fetch\" to get all the latest changes.\n\nNote that branches to fetch are identified by \"Pull: \" lines in the\nremotes file.  This is another example of the fetch/pull confusion.\ngit-pull will be explained eventually.\n\n* Remote tags\n\nTODO: Figure out how remote tags work, under what circumstances\nthey are fetched, and what git does if there are conflicts.\n\n\n* Exchanging work with other repositories, part II: git-push\n\nIt's simpler to set up git sharing on a pull basis.  If your source\ncode isn't secret, you can set up a public read-only server very easily\n(see the git-daemon man page for details), and have other fetch from that.\n\nHowever, N developers all pulling from each other is an N^2 mess.\nSome centralization helps.\n\nOne way is to have a central coordinator (like Linus) who pulls from\nall of the developers, and who they in turn pull from.\n\nThe other is to have a central repository that people can push to.\nThis generally requires an ssh login on the server.  You can use git-shell\nas the login shell if all you want to allow the account to do is git\nfetch and push.  (You can use the hook scripts to enforce rules about\nwho's allowed to do what to which branch.)\n\nGit-push to the remote machine works exactly like git-fetch from the\nremote machine.  The objects are moved over, and the branches pushed to\nare fast-forwarded.  If fast-forward is impossible, you get an error.\n\nSo if you have multiple people committing to a branch on the server,\nyou will not be allowed to push if someone has pushed more to that branch\nsince last time you fetched it.\n\nYou have to merge the changes locally, and re-try the push when you've\ngot a new head that includes the most recently pushed work as an ancestor.\n\nThis is exactly like \"cvs commit\" not working if your recent checkout\nwasn't the (current) tip of the branch, but git can upload more than\none commit.\n\nThe simplest way to resolve the conflict is to merge the remote head with\nyour local head.  This is easiest if you have different local branches\nfor fetching the remote repository and for pushing to it.\n\nThat is, you have one head that just tracks the master repository's\nmain branch, and another that you add your work to, and push from.\nThis makes merging simpler when there are conflicts.\n\n\nAnother use for git-push, even for a solo developer, is sharing your work\nwith the world.  You can set up a public git server on a high-bandwidth\nmachine (possibly rented from a hosting service) and then push to it to\npublish something.\n\n\n* Merging (finally!)\n\nI went through everything else first because the most common merge case\nis local changes with remote changes.  Not that you can't merge two\nbranches of your own, but you don't need to do that nearly as often.\n\nThe primitive that does the merging is called (guess what?) git-merge.\nAnd you can use that if you want.  If you want to create a so-called\noctopus merge, with more than two parents, you have to.\n\nHowever, it's usually easier to use the git-pull wrapper.  This merges\nthe changes from some other branch into the current HEAD and generates\na commit message automatically.\n\ngit-merge lets you specify the commit message (rather than generating it\nautomatically) and use a non-HEAD destination branch, but those options\nare usually more annoying than useful.\n\nThe basic git-pull syntax is\n\n\tgit-pull <repository> <branch>\n\nThe repository can be any URL that git supports.  Including, particularly,\na local file.  So to do a simple local merge, you just type\n\n\tgit-pull . <branch>\n\nSo after doing some hacking on branch \"foo\", you would\n\n\tgit checkout master\n\tgit pull . foo\n\nand ba-boom, all is done.\n\n\nNow, you can also specify a remote repository to merge from, using a\ngit://, http:// or git+ssh:// URL.  This is what Linus does all day long,\nand why the git-pull tool is optimized to allow that.  It uses git-fetch\nto fetch the remote branch without assigning it a branch name (it gets\nthe special name FETCH_HEAD temporarily), and them merges it into the\ncurrent HEAD directly.\n\nThere is absolutely nothing wrong with doing that, but beginners often\nfind it confusing to have a single short command do quite so much.\nAnd if you are working closely with someone, it's often more convenient\nand less confusing to keep local tracking branches.  Then you can\n\n\tgit fetch upstream\t# Fetches 'origin'\n\tgit pull . origin\n\nIt's also possible to give just a single remotes file name to git-pull:\n\n\tgit pull upstream\n\nThat does a git fetch, updating all of the listed branches as usual,\nthen merges the _first_ listed branch into HEAD.\n\nBy the way: don't blink, you might miss it!  As I mentioned, pulling is\na very big part of Linus's daily routine, and he's made sure it's fast.\n(Actually, it produces a fair bit of output, so you'll see.)\n\n\nJust to clarify, because people often get confused:\n\ngit-pull is a MERGING tool.  It always does a merge, as well as an optional\nfetch.  If you just want to LOOK at a remote branch, use git-fetch.\n\n\n* Undoing a merge\n\nIf you discover that a merge was a mistake, it can be undone just like\nany other commit.  The HEAD you merged to is the first parent, so just do\n\n\tgit reset --hard HEAD^\n\nThis is why Linus likes a git-pull command that does so much in one shot -\nif he doesn't like what he pulls, it's easy to undo.\n\n\n* How merging operates\n\nGit uses the basic three-way merge.  First, it applies it to whole files,\nand then to lines within files.\n\nTo do a three-way merge, you need three versions of a file.  The versions\nA and B you want to merge, and a common ancestor, commonly called O.\nThat is, history proceeds something like:\n\n         o--o--A\n        /\n o--o--O\n        \\\n\t o--B\n\nThe basic idea is \"I want the file O, plus all the changes made from O\nto A, plus all the changes made from O to B.\"  Since the cases where one\nof A or B is a direct ancestor of the other have already been disposed\nof, the three commits must be different.\n\nFor each file, there are a few cases that are trivial, and git gets\nthese out of the way immediately:\n\n- If A and B are identical, the merged result is obvious.\n- If O and A are the same, then the result should be B.\n- If O and B are the same, then the result should be A.\n\nIn the completely trivial case when O, A and B are the same, then\nall three rules apply, they all produce the same obvious result.\n\nThe \"merge base\" version O is generally the most recent common ancestor\nof A and B.  The only problem is, that's not necessarily unique!\n\nThe classic confusing case is called a \"criss-cross merge\", and looks\nlike this:\n\n         o--b-o-o--B\n        /    \\ /\n o--o--o      X\n        \\    / \\\n\t o--a-o-o--A\n\nThere are two common ancestors of A and B, marked a and b in the graph\nabove.  And they're not the same.  You could use either one and get\nreasonable results, but how to choose?\n\nThe details are too advanced for this discussion, but the default\n\"recursive\" merge strategy that git uses solves the answer by merging\na and b into a temporary commit and using *that* as the merge base.\n\nOf course, a and b could have the same problem, so merging them could\nrequire another merge of still-older commits.  This is why the algorithm\nis called \"recursive.\"  It's been tested with pathological conditions,\nbut multiply nested criss-cross merges are very rare, so the recursion\nisn't a performance limit in practice.\n\n\nIf all three of a given file in O, A, B are different, then the three\nversions are pulled into the index file, called \"stage 1\", \"stage 2\",\nand \"stage 3\", and a merge strategy driver is called to resolve the mess.\nGit then uses the classic line-based three-way merge, looking for isolated\nchanges and applying the same rules as for files when two of the source\nfiles are the same in some range.\n\n\n* Alternate merge strategies\n\nIn every version control system prior to git, the merging algorithm was\nburied deep in the bowels of the software, and very difficult to change.\nOne of particularly nice things that git did was allow for easily\nreplaceable \"merge strategies\".  Indeed, you can try multiple merge\nstrategies, and the fallback - print an error message and let the user\nsort it out - can be thought of as just another merge strategy.\n\nEnabling this is why the index is so important to git.  It provides a\nplace to store an unfinished merge, so you can try various strategies\n(including hand-editing) to finish it.\n\nGenerally, git's default merge strategies are just fine.  There is,\nhowever, one special case that is occasionally useful, specified with the\n\"-s ours\" strategy.\n\nThat strategy instructs git that the merged result should be the same\nas the current HEAD.  Any other branches are recorded as parents, but\ntheir contents are ignored.\n\nWhat the heck is the use of that?  Well, it lets you record the fact\nthat some work has been done in the history, and that it shouldn't be\nmerged again.  For example, say you write and share a popular patch set.\nPeople are always merging it in to their local source trees.  But then\nyou discover a much better way to achieve the goal of that patch set, and\nyou want to publish the fact that the new patch supersedes the old one.\n\nIf you developed the new set starting from the old one, that would happen\nautomatically.  But another way to achieve the same goal is to merge the\nold branch it in using the \"ours\" strategy.  Everyone else's git will\nnotice that the patch is already included, and stop trying to merge it in.\n\n\n* When merging goes wrong\n\nThis is the fun part.  Git's default recursive-merge strategy is pretty\nclever, but sometimes changes truly do conflict and need manual fix-up.\n\nWhen git is unable to complete a merge, it leaves the three different\nversions in the index and places a file with CVS-style conflict markers\nin the working directory.\n\nAs long as there is a \"staged\" file in the index, you will not be able\nto commit.  You must resolve the conflict, and update the index with the\nresolved versions.  You can do this one at a time with git-update-index,\nor at the end by giving the files as arguments to git-commit.\n\nDoing them one at a time is probably safest; checking in a file which still\nhas conflict markers makes a bit of a mess.  Note that git will still\nuse the automatically generated commit message when you finally commit.\n(It's in .git/MERGE_MSG, if you care.)\n\nNote that \"git diff\" knows how to be useful with a staged file.\nBy default, it displays a multi-way diff.  For example, suppose I take a\n(slightly buggy) hello.c:\n\n--- hello.c ---\n#include <stdio.h>\n\nint main(void)\n{\n\tprintf(\"Hello, world!\");\n}\n--- end ---\n\nNow, suppose that in branch A, I fix some bugs - add the missing newline\nand \"return 0;\".  In branch B, I display my angst and change it to\n\"Goodbye, cruel world!\".  When I try to merge A into B, obviously I'll\nget a conflict.  The resultant file, with conflict markers, looks like:\n\n--- hello.c ---\n#include <stdio.h>\n\nint\nmain(void)\n{\n<<<<<<< HEAD/hello.c\n        printf(\"Goodbye, cruel world!\");\n=======\n\tprintf(\"Hello, world!\\n\");\n\treturn 0;\n>>>>>>> edadc53fc7a8aef2a672a4fa9d09aa16f4e14706/hello.c\n}\n--- end ---\n\nand the result of \"git diff\" is\n\ndiff --cc hello.c\nindex 4b7f550,948a5f8..0000000\n--- a/hello.c\n+++ b/hello.c\n@@@ -3,5 -3,6 +3,10 @@@\n  int\n  main(void)\n  {\n++<<<<<<< HEAD/hello.c\n +      printf(\"Goodbye, cruel world!\");\n++=======\n+       printf(\"Hello, world!\\n\");\n+       return 0;\n++>>>>>>> edadc53fc7a8aef2a672a4fa9d09aa16f4e14706/hello.c\n  }\n\nNotice how this is not a standard diff!  It has two columns of diff\nsymbols, and shows the difference from each of the ancestors to the\ncurrent hello.c contents.  I can also use \"git diff -1\" to compare\nagainst the common ancestor, or \"-2\" or \"-3\" to compare against each of\nthe merged copies individually.\n\n\n* Alternatives to merging\n\nThe bigger and more active your source tree, the more important it is to\nkeep the history reasonably clean.  Just because git can do a merge in\nunder a second doesn't mean that you should do one daily.  When you look\nback at a feature's development history, you'd like to see meaningful\nchanges recorded and not a lot of meaningless ones.\n\nNow, once you have shared a commit with others, and they have incorporated\nit into their development, it becomes impossible to undo.  But git\nprovides tools that are useful for \"rewriting history\" before public\nrelease.  These can be used to edit a commit for publication.\n\n* Test merging\n\nOne way to keep the history clean is to simply not merge other branches\ninto your development branch.  If you want to use your new features and\nother people's code changes, make a test merge and use that, but don't\nmake that merge part of your branch.\n\nThis is slightly more work (you have to change to a test branch and do\nyour merging there), but not very much.\n\nSometimes, when doing this, a conflict appears between your changes and\nsomeone else's development.  If you get tired of fixing the same conflict\nevery time you do a test merge, have a look at the git-rerere tool.\nThis remembers resolved conflicts and tries to apply the same resolution\npatch the next time.\n\nIt's written specifically to help you not do an extra merge unnecessarily.\nAlthough its man page is well worth reading, you never invoke git-rerere\nexplicitly; it's invoked automatically by the merge and patch tools if\nyou create a .git/rr-cache directory.\n\n* Cherry picking\n\nIf you have a series of patches on a branch, but you want a subset\nof them, or in a different order, there's a handy utility called\n\"git-cherry-pick\" which will find the diff and apply it as a patch to\nthe current HEAD.  It automatically recycles the commit message from\nthe original commit.\n\nIf the patch can't be applied, it leaves the versions in the index and\nconflict markers in the working directory just like a failed merge.\nAnd just like a merge, it remembers the commit message and provides it\nas a default when I finally commit.\n\nNote that this can only work on a chain of single-parent commits.\nIf a commit has multiple parents, there's no single patch to apply.\n\n\nYou van get the list of commits on a branch with git-log or git-rev-list,\nbut for more complex cases, the git-cherry tool is designed to generate\nthe list of commits to merge.  It has a rather neat approximate-match\nfunction built in which identifies patches that appear to already be\npresent in the target branch.\n\n* Rebasing\n\nA special case of cherry-picking is if you want to move a whole branch\nto a newer \"base\" commit.  This is done by git-rebase.  You specify\nthe branch to move (default HEAD) and where to move it to (no default),\nand git cherry-picks every patch out of that branch, applies it on top\nof the target, and moves the refs/heads/<branch> pointer to the newly\ncreated commits.\n\nBy default, \"the branch\" is every commit back to the last common\nancestor of the branch head and the target, but you can override that\nwith command-line arguments.\n\nIf you want to avoid merge conflicts due to the master code changing out\nfrom under your edits, but not have \"cleanup\" merges in your history,\ngit-rebase is the tool to use.\n\nGit-rebase will also use git-rerere if enabled (\"mkdir .git/rr-cache\").\n\n\nIf rebasing encounters a conflict it can't resolve, it will stop halfway\nand ask you to resolve the problem by hand.  However, it still knows it\nhas a job to finish!  The unapplied patches are remembered until you do\none of\n\n\tgit-rebase --continue\n\t\tThis will check in the current index.  You should\n\t\tdo git-update-index <files> in the conflicts that\n\t\tyou resolve, but NOT do an actual git-commit.\n\t\tgit-rebase --continue will do the commit.\n\tgit-rebase --skip\n\t\tThis will skip the conflicting patch.  You\n\t\tdon't have to resolve the conflicts; git will\n\t\tjust back up and try the next patch in the series.\n\tgit-rebase --abort\n\t\tThis will abandon the whole rebase operation (including\n\t\tany half-done work) and return you to where you began.\n\n\nGit-rebase can also help you divide up work.  Suppose you've mixed up\ndevelopment of two features in the current HEAD, a branch called \"dev\".\nYou want to divide them up into \"dev1\" and \"dev2\".  Assuming that HEAD\nis a branch off master, then you can either look through\n\n\tgit log master..HEAD\nor just get a raw list of the commits with\n\tgit rev-list master..HEAD\n\nEither way, suppose you figure out a list of commits that you want in\ndev1 and create that branch:\n\n\tgit checkout -b dev1 master\n\tfor i in `cat commit_list`; do\n\t\tgit-cherry-pick $i\n\tdone\n\nYou can use the other half of the list you edited to generate the dev2\nbranch, but if you're not sure if you forgot something, or just don't\nfeel like doing that manual work, then you can use git-rebase to do it\nfor you...\n\n\tgit checkout -b dev2 dev\t# Create dev2 branch\n\tgit-rebase --onto master dev1\t# Subreact dev1 and rebase\n\nThis will find all patches that are in dev and not in dev1,\napply them on top of master, and call the result dev2.\n\n\n* Experimenting with merging\n\nTo play with non-trivial merging, get an existing git repository of\na non-trivial project (git itself and the Linux kernel are readily\navailable.  Fire up gitk to look at history, find some interesting-looking\nmerges, and redo them yourself on a test branch.\n\nAs long as you do everything on test branches, you aren't going to screw\nanything up.  So play!\n\nYou can use gitk to search for \"Conflicts:\" in the commit comments to\nfind merges that didn't go smoothly and see what happens.  (Or you can\nsearch in \"git log\" output.  gitk just draws prettier pictures.)\n\nYou can also set up two repositories on the same machine and try pulling\nand pushing between them.\n\nTo identify arbitrary commits, the 40-byte raw hex ID is probably easiest;\nyou can cut-and-paste them from the gitk window.\n\nFor example, in the git repository,\n3f69d405d749742945afd462bff6541604ecd420\n\nlooks like an interesting merge.  Its parents are\nParent: 7d55561986ffe94ca7ca22dc0a6846f698893226\nParent: 097dc3d8c32f4b85bf9701d5e1de98999ac25c1c\n\nLet's try doing that manually:\n\n$ git checkout -b test 7d55561986ffe94ca7ca22dc0a6846f698893226\n$ git pull . 097dc3d8c32f4b85bf9701d5e1de98999ac25c1c\nerror: no such remote ref refs/heads/097dc3d8c32f4b85bf9701d5e1de98999ac25c1c\nFetch failure: .\n\nCool!  I didn't know that wasn't allowed.  (I'll have to ask why it's\nnot; perhaps it's because it uses the branch name in the automatic\ncommit message.)  I could do it by hand with git-merge, but I'll just\ngive it a branch name:\n\n$ git branch test2 097dc3d8c32f4b85bf9701d5e1de98999ac25c1c\n$ git pull . test2\nMerging HEAD with 097dc3d8c32f4b85bf9701d5e1de98999ac25c1c\nMerging:\n7d55561986ffe94ca7ca22dc0a6846f698893226 Merge branch 'jc/dirwalk-n-cache-tree' into jc/cache-tree\n097dc3d8c32f4b85bf9701d5e1de98999ac25c1c Remove \"tree->entries\" tree-entry list from tree parser\nfound 2 common ancestor(s):\nd9b814cc97f16daac06566a5340121c446136d22 Add builtin \"git rm\" command\n288c0384505e6c25cc1a162242919a0485d50a74 Merge branch 'js/fetchconfig'\n  Merging:\n  d9b814cc97f16daac06566a5340121c446136d22 Add builtin \"git rm\" command\n  288c0384505e6c25cc1a162242919a0485d50a74 Merge branch 'js/fetchconfig'\n  found 1 common ancestor(s):\n  63dffdf03da65ddf1a02c3215ad15ba109189d42 Remove old \"git-grep.sh\" remnants\n  Auto-merging Makefile\nmerge: warning: conflicts during merge\n  CONFLICT (content): Merge conflict in Makefile\n  Auto-merging builtin.h\nmerge: warning: conflicts during merge\n  CONFLICT (content): Merge conflict in builtin.h\n  Auto-merging cache.h\n  Removing check-ref-format.c\n  Auto-merging git.c\nmerge: warning: conflicts during merge\n  CONFLICT (content): Merge conflict in git.c\n  Auto-merging read-cache.c\n  Auto-merging update-index.c\nmerge: warning: conflicts during merge\n  CONFLICT (content): Merge conflict in update-index.c\nRenaming apply.c => builtin-apply.c\nAuto-merging builtin-apply.c\nRenaming read-tree.c => builtin-read-tree.c\nAuto-merging builtin-read-tree.c\nAuto-merging .gitignore\nAuto-merging Makefile\nmerge: warning: conflicts during merge\nCONFLICT (content): Merge conflict in Makefile\nAuto-merging builtin.h\nmerge: warning: conflicts during merge\nCONFLICT (content): Merge conflict in builtin.h\nAuto-merging cache.h\nAuto-merging fsck-objects.c\nRemoving git-format-patch.sh\nAuto-merging git.c\nmerge: warning: conflicts during merge\nCONFLICT (content): Merge conflict in git.c\nAuto-merging update-index.c\nAutomatic merge failed; fix conflicts and then commit the result.\n\n$ git status\nHey, look, lots of interesting stuff.  Particularly, see\n# Changed but not updated:\n#   (use git-update-index to mark for commit)\n#\n#       unmerged: Makefile\n#       modified: Makefile\n#       unmerged: builtin.h\n#       modified: builtin.h\n#       unmerged: git.c\n#       modified: git.c\n\nThe \"unmerged\" (a.k.a. \"staged\") files are ones that need manual resolution.\n\n(I notice that update-index.c isn't listed, despite being mentioned\nas a conflict in the message.  Can someone explain that?)\n\nFixing those is easy, but as you can see from the original commit comment\nand diffs, there were some additional changes that were necessary to\nmake that compile.\n\nYou can test before committing the change, or do it the git way - commit\nanyway, then test and \"git commit --amend\" with the fixes, of any.\n\nUnlike a centralized VCS, committing is not the same as pushing upstream.\nYou can use test branches in the repository to save as much work as\nyou like.  While it's still nice to keep the public repository clean,\nyou don't have to worry about \"breaking the tree\" every time you commit.\nYou can do all kinds of stuff in test branches, and clean it up later.\n\nThis is why all the git merge tools do the commit without waiting for\nyou to test it.  The merge is usually okay, and it saves time.  If not,\n"},{"id":"295687","messageId":"ejjvqr$k0v$1@sea.gmane.org","threadId":"6207","inReplyTo":"20061116221701.4499.qmail@science.horizon.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-17T09:37:50Z","receivedAt":"2006-11-17T09:37:50Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"linux@horizon.com wrote:\n\n> Either way, they're just a 41-byte file that contains a 40-byte hex\n> object ID, plus a newline.  Tags are stored in .git/refs/tags, and heads\n> are stored in .git/refs/heads.  Creating a new branch is literally just\n> picking a file name and writing the ID of an existing commit into it.\n\nThis is an implementation detail, and is not true in repository with\npacked refs. Although usually (by default) only tags are packed.\n\nBut it remains true that ref (be it branch or tag) is just name and ID.\n\n> The git programs enforce the immutability of tags, but that's a safety\n> feature, not something fundamental.  You can rename a tag to the heads\n> directory and go wild.\n\nYou can have only refs to commit objects in heads directory (and I hope\nthis is verified by fsck-objects), you can have refs to tag objects\n(heavyweight tags), to commits (lightweight tags), to blobs (for example\npublic PGP key used for signing tags), to trees (I guess unused).\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"294927","messageId":"ejk01n$l9u$1@sea.gmane.org","threadId":"6207","inReplyTo":"20061116221701.4499.qmail@science.horizon.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-17T09:41:29Z","receivedAt":"2006-11-17T09:41:29Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"linux@horizon.com wrote:\n\n> There is always a current head, known as HEAD.  (This is actually a\n> symbolic link, .git/HEAD, to a file like refs/heads/master.)\n\nUsually this is symref, not symlink, i.e. .git/HEAD (or rather\n$GIT_DIR/HEAD) is a file which contains single line like this:\n\n  ref: refs/heads/master\n\nThere is a talk about relaxing HEAD restriction to allow it to contain ref\nto tag, or bare SHA1 id for \"seeking\"; you are forbidden to commit to such\nstate.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"297743","messageId":"ejk3bf$veg$1@sea.gmane.org","threadId":"6207","inReplyTo":"20061116221701.4499.qmail@science.horizon.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-17T10:37:54Z","receivedAt":"2006-11-17T10:37:54Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"linux@horizon.com wrote:\n\n> * Remotes files\n> \n> You can specify what to fetch on the git-fetch command line.  However,\n> if you intend to monitor another repository on an ongoing basis,\n> it's generally easier to set up a short-cut by placing the options in\n> .git/remotes/<name>.\n\nYou can also set up this in config file (remote and branch sections),\nin modern git.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"297428","messageId":"20061117153246.GA20065@thunk.org","threadId":"6207","inReplyTo":"20061116221701.4499.qmail@science.horizon.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2006-11-17T15:32:46Z","receivedAt":"2006-11-17T15:32:46Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Thu, Nov 16, 2006 at 05:17:01PM -0500, linux@horizon.com wrote:\n> I know it took me a while to get used to playing with branches, and I\n> still get nervous when doing something creative.  So I've been trying\n> to get more comfortable, and wrote the following to document what I've\n> learned.\n> \n> It's a first draft - I just finished writing it, so there are probably\n> some glaring errors - but I thought it might be of interest anyway.\n\nThis is really, really good stuff that you've written!  Have you any\nthoughts or suggestions about where this text should end up?\nPersonally, I think this information is actually more important to an\nend-user than the current \"part two\" of the tutorial, which discusses\nthe object database and the index file.  Perhaps this should be \"part\n2\", and the object database and index file should become \"part 3\"?  \n\nIt might also be a good to consider moving some of the \"discussion\"\nportion the top-level git(7) man page into the object database and\nindex file discussion.  Right now, the best way to introduce git's\nconcepts (IMHO), is to start with the part 1 of the tutorial, then go\ninto the your draft branch/merging with git, then the current part 2\nof the tutorial, and then direct folks to read the \"discussion\"\nsection of git(7).  Only then do they really have enough background\nunderstanding of the fundamental concepts of git that they won't get\nconfused when they start talking to other git users, on the git\nmailing list, for example.\n\nIt would be nice if there was an easy way to direct users through the\ndocumentation in a way which makes good pedagogical sense.  Right now,\none of the reasons why life gets hard for new users is that the\ncurrent tutorials aren't enough for them to really undersatnd what's\ngoing on at a conceptual level.  And if users start using \"everyday\ngit\" as a crutch, without the right background concepts, the human\nbrain naturally tries to intuit what's happening in the background,\nbut without reading the background docs, git is different enough that\nthey will probably get it wrong, which means more stuff that they have\nto unlearn later.  \n\n> * Git's representation of history\n> \n> As you recall from Git 101, there are exactly four kinds of objects in\n> Git's object database.  All of them have globally unique 40-character hex\n> names made by hashing their type and contents.  Blob objects record file\n> contents; they contain bytes.  Tree objects record directory contents;\n> they contain file names, permissions, and the associated tree or blob\n> object names.  Tag objects are shareable pointers to other objects;\n> they're generally used to store a digital signature.\n\nHmm... this assumes that you've read the Git(7) discussion first.\nThere is enough information here though that maybe you don't need to\nsay \"as you recall\".  It might be enough to give a quick summary of\nthe concepts that are needed to understand the rest of your tutorial,\nand then point to git(7) Discussion section for people who need to\nlearn more details.\n\n> * Remotes files\n> \n> Note that branches to fetch are identified by \"Pull: \" lines in the\n> remotes file.  This is another example of the fetch/pull confusion.\n> git-pull will be explained eventually.\n\nMaybe we should change git so that a \"Fetch: \" line in the remotes\nfile works the same way as \"Pull: \", and then recommend that people\nuse \"Fetch: \" in order to reduce confusion, as opposed to simply\nexplaining it away as \"yet another example of the histororical\nfetch/pull confusion\"?\n\nThanks,\n\n"},{"id":"297105","messageId":"BAYC1-PASMTP07C8A8D8E5E78173953CA9AEE80@CEZ.ICE","threadId":"6207","inReplyTo":"20061117153246.GA20065@thunk.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Sean","fromEmail":"seanlkml@sympatico.ca","sentAt":"2006-11-17T15:57:48Z","receivedAt":"2006-11-17T15:57:48Z","isPatch":false,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Fri, 17 Nov 2006 10:32:46 -0500\nTheodore Tso <tytso@mit.edu> wrote:\n\n> It would be nice if there was an easy way to direct users through the\n> documentation in a way which makes good pedagogical sense.  Right now,\n> one of the reasons why life gets hard for new users is that the\n> current tutorials aren't enough for them to really undersatnd what's\n> going on at a conceptual level.  And if users start using \"everyday\n> git\" as a crutch, without the right background concepts, the human\n> brain naturally tries to intuit what's happening in the background,\n> but without reading the background docs, git is different enough that\n> they will probably get it wrong, which means more stuff that they have\n> to unlearn later.  \n\nIt would be nice to post this information on the Git website and not\nhave it overshadowed by Cogito examples with paragraphs explaining how\nCogito makes things easier.  The current website distracts users away\nfrom learning Git or ever reading about this kind of information.\nMaybe we can pass a hat around for some funds for a separate Cogito\nwebsite. ;o)\n\n> Maybe we should change git so that a \"Fetch: \" line in the remotes\n> file works the same way as \"Pull: \", and then recommend that people\n> use \"Fetch: \" in order to reduce confusion, as opposed to simply\n> explaining it away as \"yet another example of the histororical\n> fetch/pull confusion\"?\n \nThat's quite a good idea.  The name was fixed when the option to move\nthis info into the config file was added (remote.<name>.fetch).  So\nanother option would be to show new users the config file method and\njust damn the remotes file to a historical footnote.\n\n"},{"id":"293818","messageId":"fcaeb9bf0611170819j57cda9e1ia4ecd4cd13956447@mail.gmail.com","threadId":"6207","inReplyTo":"BAYC1-PASMTP07C8A8D8E5E78173953CA9AEE80@CEZ.ICE","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2006-11-17T16:19:23Z","receivedAt":"2006-11-17T16:19:23Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On 11/17/06, Sean <seanlkml@sympatico.ca> wrote:\n> It would be nice to post this information on the Git website and not\n> have it overshadowed by Cogito examples with paragraphs explaining how\n> Cogito makes things easier.  The current website distracts users away\n> from learning Git or ever reading about this kind of information.\n> Maybe we can pass a hat around for some funds for a separate Cogito\n> website. ;o)\n\nOr.. find a way to merge cogito back to git :-)\n/me runs into a nearest bush.\n-- \n"},{"id":"296372","messageId":"455DE275.8020000@gmx.net","threadId":"6207","inReplyTo":"fcaeb9bf0611170819j57cda9e1ia4ecd4cd13956447@mail.gmail.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Marko Macek","fromEmail":"marko.macek@gmx.net","sentAt":"2006-11-17T16:25:25Z","receivedAt":"2006-11-17T16:25:25Z","isPatch":false,"sender":{"key":"marko.macek@gmx.net","avatar":null},"body":"Nguyen Thai Ngoc Duy wrote:\n> On 11/17/06, Sean <seanlkml@sympatico.ca> wrote:\n>> It would be nice to post this information on the Git website and not\n>> have it overshadowed by Cogito examples with paragraphs explaining how\n>> Cogito makes things easier.  The current website distracts users away\n>> from learning Git or ever reading about this kind of information.\n>> Maybe we can pass a hat around for some funds for a separate Cogito\n>> website. ;o)\n> \n> Or.. find a way to merge cogito back to git :-)\n> /me runs into a nearest bush.\n\nI agree, this would certainly be the best solution. But it would imply\nhiding the 'index' by default which would probably an incompatible change.\n\nThe alternative would be to explain that git is a low level tool suitable \nmostly for integrators like Linus (that, and that Cogito and/or StGit should \nbe used by developers/contributors).\n\n"},{"id":"297566","messageId":"20061117163341.GQ4842@pasky.or.cz","threadId":"6207","inReplyTo":"455DE275.8020000@gmx.net","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-11-17T16:33:41Z","receivedAt":"2006-11-17T16:33:41Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, Nov 17, 2006 at 05:25:25PM CET, Marko Macek wrote:\n> Nguyen Thai Ngoc Duy wrote:\n> >On 11/17/06, Sean <seanlkml@sympatico.ca> wrote:\n> >>It would be nice to post this information on the Git website and not\n> >>have it overshadowed by Cogito examples with paragraphs explaining how\n> >>Cogito makes things easier.  The current website distracts users away\n> >>from learning Git or ever reading about this kind of information.\n> >>Maybe we can pass a hat around for some funds for a separate Cogito\n> >>website. ;o)\n> >\n> >Or.. find a way to merge cogito back to git :-)\n> >/me runs into a nearest bush.\n\nI think we are trying to figure that out in the last few days in those\nmammoth threads. UI-wise with no big breakthroughs so far I guess,\nthough.\n\n> The alternative would be to explain that git is a low level tool suitable \n> mostly for integrators like Linus (that, and that Cogito and/or StGit \n> should be used by developers/contributors).\n\nThis is in essence what many people (including Junio) are saying. I'm\nnot saying it's a totally great situation, hence the previous paragraph.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\n#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj\n$/=unpack('H*',$_);$_=`echo 16dio\\U$k\"SK$/SM$n\\EsN0p[lN*1\n"},{"id":"295030","messageId":"BAYC1-PASMTP021B5A7CD192CD4D37A152AEE80@CEZ.ICE","threadId":"6207","inReplyTo":"fcaeb9bf0611170819j57cda9e1ia4ecd4cd13956447@mail.gmail.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Sean","fromEmail":"seanlkml@sympatico.ca","sentAt":"2006-11-17T16:34:04Z","receivedAt":"2006-11-17T16:34:04Z","isPatch":false,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Fri, 17 Nov 2006 23:19:23 +0700\n\"Nguyen Thai Ngoc Duy\" <pclouds@gmail.com> wrote:\n\n\n> Or.. find a way to merge cogito back to git :-)\n> /me runs into a nearest bush.\n\nPasky has already given a lot to Git, and it would be great to see even\nmore merged back into Git where a consensus can be reached.  In fact\nPasky has said that his plan is to push a lot more towards Git and\nmake Cogito a thinner UI layer.  Either way, there's absolutely nothing\nwrong with people choosing to use Cogito rather than Git.  It's just\nthat the separate Cogito tool shouldn't have a place on the Git website\nany more prominent than say StGit does.\n\nThe Git website should be a place where Git makes the best case\nit can for _itself_, not for its sister tools.  It's a distraction\nand gets in the way of promoting Git as a stand alone tool.  At\nleast one new user has complained that it was confusing.\n\nPersonally I have nothing against Cogito, I just think Pasky should\nseparate his role as Git webmaster from his role as Cogito author.\nIf people have good ideas for Git documentation, the website would be\na natural place for it, and it shouldn't have to compete with Cogito\ntutorials etc.\n\n"},{"id":"294586","messageId":"20061117165333.GR4842@pasky.or.cz","threadId":"6207","inReplyTo":"20061117113404.810fd4ea.seanlkml@sympatico.ca","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-11-17T16:53:33Z","receivedAt":"2006-11-17T16:53:33Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, Nov 17, 2006 at 05:34:04PM CET, Sean wrote:\n> It's just that the separate Cogito tool shouldn't have a place on the\n> Git website any more prominent than say StGit does.\n\nIt doesn't - look at the \"Maintaining external patches\" crash course.\n\nPorcelains are integral part of the Git environment. I think several\npeople have already tried to explain it before.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\n#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj\n$/=unpack('H*',$_);$_=`echo 16dio\\U$k\"SK$/SM$n\\EsN0p[lN*1\n"},{"id":"293993","messageId":"BAYC1-PASMTP07E3595705250158235B01AEE80@CEZ.ICE","threadId":"6207","inReplyTo":"20061117165333.GR4842@pasky.or.cz","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Sean","fromEmail":"seanlkml@sympatico.ca","sentAt":"2006-11-17T17:01:54Z","receivedAt":"2006-11-17T17:01:54Z","isPatch":false,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Fri, 17 Nov 2006 17:53:33 +0100\nPetr Baudis <pasky@suse.cz> wrote:\n\n> On Fri, Nov 17, 2006 at 05:34:04PM CET, Sean wrote:\n> > It's just that the separate Cogito tool shouldn't have a place on the\n> > Git website any more prominent than say StGit does.\n> \n> It doesn't - look at the \"Maintaining external patches\" crash course.\n> \n> Porcelains are integral part of the Git environment. I think several\n> people have already tried to explain it before.\n> \n\nThere is enough native Git documentation and hopefully more coming\nthat third party tools should be pushed behind the scenes a bit.\nAt least on the GIT website.\n\nOf course there is nothing wrong with having information there, but\nthe main thrust should be about Git and how to use it directly without\nporcelains.  Especially in the light that people have recently\nexpressed a desire to advocate and document the use of native Git\nmore strongly.\n\nHaving a link to Cogito off the front page of the Git website that\nsays... Cogito makes things \"easier\", no matter how much you\npersonally believe it, isn't the way everyone feels and is at\nodds with the native-git message and improvement effort.\n\n"},{"id":"296352","messageId":"20061117174446.GB11882@fieldses.org","threadId":"6207","inReplyTo":"20061116221701.4499.qmail@science.horizon.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2006-11-17T17:44:46Z","receivedAt":"2006-11-17T17:44:46Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"This has some useful material that fills gaps in the existing\ndocumentation.  We need to think a little more about the intended\naudience, and about how to fit it in with existing documentation.\n\nOn Thu, Nov 16, 2006 at 05:17:01PM -0500, linux@horizon.com wrote:\n> * A brief digression on command names.\n> \n> Originally, all git commands were named \"git-foo\".  When there got to\n> be over a hundred, people started complaining about the clutter in\n> /usr/bin.  After some discussion, the following solution was reached:\n> \n> - It's now possible to place all of the git-foo commands into a separate\n>   directory.  (Despite the complaints, not too many people are doing it\n>   yet.)\n> - One option for git users is to add that directory to their $PATH.\n> - Another is provided by a wrapper called just \"git\".  It's intended to\n>   live in a public directory like /usr/bin, and knows the location of\n>   the separate directory.  When you type \"git foo\", it finds and executes\n>   \"git-foo\".\n> - Some simple commands are built into the git wrapper.  When you type\n>   \"git add\", it just does it internally.  (On the git mailing list,\n>   you will see patches like \"make git diff a builtin\"; this is what\n>   they're talking about.)\n> - For compatibility, for each builtin, there is a \"git-add\" file,\n>   which is just a link to the \"git\" wrapper.  It looks at the name it\n>   was invoked as to figure out what it should do.\n> \n> The one confusing thing is that, although people usually type \"git foo\"\n> in examples, they're interchangeable in practice.  I go back and forth\n> for no good reason.  The main caveat is that to get the man page, you\n> still need to type \"man git-foo\".  Fortunately, there are two other ways\n> to get the man page:\n> \n> \t1) \"git help foo\"\n> \t2) \"git foo --help\"\n> \n> Git doesn't have a specialized built-in help system; it just shows you\n> the man pages.\n\nWho's the audience for the above?  I can see that it's useful for\nadministrators, who may need help deciding how to install stuff, and for\ndevelopers, who need to know where the heck the code for \"git-add\" came\nfrom.  But the case I'm most interested in is the user whose\ndistribution installs git for them, in which case I think the above\ncould be distilled down to:\n\n\t- \"git-foo\" and \"git foo\" can be used interchangeably.\n\t- Documentation for the command foo is available from any of\n\t\t- man git-foo\n\t\t- git help foo\n\t\t- git foo --help\n\nThen the additional details above could be postponed to a later part of\nthe documentation.\n\n> One outstanding problem with git's man pages is that often the most detail\n> is in the command page that was written first, not the user-friendly\n> one that you should use.  For example, there are a number of special\n> cases of the \"git diff\" command that were written first, and the man\n> pages for these commands (git-diff-index, git-diff-files, git-diff-tree,\n> and git-diff-stages) are considerably more informative than the page for\n> plain git-diff, even though that's the command that you should use 99%\n> of the time.\n\nI agree that that's helpful.  Though we should probably also be working\non the man pages to make this organization clearer.\n\n> As you recall from Git 101\n\nObviously a more specific reference would be more useful here--if\nthere's nothing useful to point to among the existing documentation, we\nshould figure out how to fix that problem.\n\nThat might also remove the need for some of the recap that follows.\n\n> there are exactly four kinds of objects in\n> Git's object database.  All of them have globally unique 40-character hex\n....\n\n\n> Finally, there are references, stored in the .git/refs directory.\n> These are the human-readable names associated with commits, and the\n> \"root set\" from which all other commits should be reachable.\n\nThis is good; a comprehensive discussion of references will fill a gap\nin the current documentation.\n\n....\n\n> * Naming revisions\n> \n> CVS encourages you to tag like crazy, because the only other way to\n> find a given revision is by date.  Git makes it a lot easier, so most\n> revisions don't need names.\n> \n> You can find a full description in the git-rev-parse man page, but here's\n> a summary.\n\nThis has a lot more overlap with existing documentation.  The extra\ndetail is useful, but we need to decide what our audience and goal is\nhere, to decide exactly what niche we're trying to fill between the\nbrief stuff that's in the tutorial part I and the details in\n\"man git-rev-parse\".\n\n> * Converting between names\n> \n> Git has two helpers (programs designed mainly for use in shell scripts)\n> to convert between global object IDs and human-readable names.\n> \n> The first is git-rev-parse.  This is a general git shell script helper,\n> which validates the command line and converts object names to absolute\n> object IDs.  Its man page has a detailed description of the object\n> name syntax.\n> \n> The second is git-name-rev, which converts the other way around.  It's\n> particularly useful for seeing which tags a given commit falls between.\n\nAlso discuss git-describe?\n\n> * The three uses of \"git checkout\"\n\nObviously there's a lot of overlap here with \"man git-checkout\".  What's\nthe goal here?  Maybe this should just be worked in to a revision of\nthat man page?\n\n> * Deleting branches\n> \n> \"git branch -d <head>\" is safe.  It deletes the given <head>, but first\n> it checks that the commit is reachable some other way.  That is, you\n> merged the branch in somewhere, or you never did any edits on that branch.\n\nIt only checks whether the head of the branch to delete is reachable\nfrom the *current* branch.  The man page could be clearer here.\n\n....\n\n> * Examining history: git-log and git-rev-list\n\nYep, we should definitely have a good long chapter just devoted to\nhistory examination.  Most of it could be just cool examples, so it\nwould be fun.\n\nNote some of this is done in the last half of cvs-migration.txt; we\nshould mine that section for whatever's useful and then replace by a\nreference to the new chapter.\n\n> * History diagrams\n...\n\n> * Trivial merges: fast-forward and already up-to-date.\n\nThese two sections are useful, yep.\n\n> * Exchanging work with other repositories, part II: git-push\n\nThere's a lot of overlap here with cvs-migration.txt.  Maybe some better\norganization is needed to make that more prominent.\n\n> The details are too advanced for this discussion, but the default\n> \"recursive\" merge strategy that git uses solves the answer by merging\n> a and b into a temporary commit and using *that* as the merge base.\n\nI'm tempted to ignore any description of the merge strategy, or postpone\nit till later; as a first pass I think it's better just to say \"obvious\ncases will be handled automatically, and you'll be prompted for\ncomments.\"  Only other SCM developers are going to wonder how you handle\nthe corner cases.\n\n> * When merging goes wrong\n\nBut yes, I think people could use more help on how to resolve merges.\n\n> * Test merging\n...\n> * Cherry picking\n...\n> * Rebasing\n\nYup, I agree that that's good material to cover together.\n\n"},{"id":"295787","messageId":"ejku76$7pr$1@sea.gmane.org","threadId":"6207","inReplyTo":"20061117174446.GB11882@fieldses.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-17T18:16:26Z","receivedAt":"2006-11-17T18:16:26Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"J. Bruce Fields wrote:\n\n> This has some useful material that fills gaps in the existing\n> documentation.  We need to think a little more about the intended\n> audience, and about how to fit it in with existing documentation.\n> \n> On Thu, Nov 16, 2006 at 05:17:01PM -0500, linux@horizon.com wrote:\n>> * A brief digression on command names.\n\n> But the case I'm most interested in is the user whose\n> distribution installs git for them, in which case I think the above\n> could be distilled down to:\n> \n>       - \"git-foo\" and \"git foo\" can be used interchangeably.\n\nBut it is encouraged (also for example by git-completion.bash) to use \n\"git foo\" form in command line (because git commands can be not in the PATH,\nalthough usually they are), and \"git-foo\" form in scripts (if possible).\n\n>> The details are too advanced for this discussion, but the default\n>> \"recursive\" merge strategy that git uses solves the answer by merging\n>> a and b into a temporary commit and using *that* as the merge base.\n> \n> I'm tempted to ignore any description of the merge strategy, or postpone\n> it till later; as a first pass I think it's better just to say \"obvious\n> cases will be handled automatically, and you'll be prompted for\n> comments.\"  Only other SCM developers are going to wonder how you handle\n> the corner cases.\n\nSee below...\n \n>> * When merging goes wrong\n> \n> But yes, I think people could use more help on how to resolve merges.\n\nIt would be useful to cover all non-reductible cases of recursive merge\nstrategy (the default merge strategy for two-head merges) conflicts: \ncontents (covered), add/add, rename/modify etc.\n\nSo some info about recirsive merge strategy would be useful.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"297830","messageId":"20061117213125.GG7201@pasky.or.cz","threadId":"6207","inReplyTo":"20061117120154.3eaf5611.seanlkml@sympatico.ca","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-11-17T21:31:26Z","receivedAt":"2006-11-17T21:31:26Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, Nov 17, 2006 at 06:01:54PM CET, Sean wrote:\n> There is enough native Git documentation and hopefully more coming\n> that third party tools should be pushed behind the scenes a bit.\n> At least on the GIT website.\n\nIt's not about documentation but ease to use. I agree and sympathise\nvery much with the effort of making core Git more easy to use and\nobsoleting Cogito, but until it gets there we should have what's nicest\nto the users.\n\n> Of course there is nothing wrong with having information there, but\n> the main thrust should be about Git and how to use it directly without\n> porcelains.  Especially in the light that people have recently\n> expressed a desire to advocate and document the use of native Git\n> more strongly.\n\nIf someone writes a crash course in pure Git covering the same grounds\nas the current ones (possibly by just extending/retouching the tutorial)\n(it does not necessarily need to be a \"refugee\" crash course, it can\nbuild up from scratch), I can add it on the web. If it becomes as easy\nto use and with as mild learning curve as Cogito, it means Cogito got\nmostly obsolete and I'll happily remove the Cogito crash courses from\nthe web.\n\n> Having a link to Cogito off the front page of the Git website that\n> says... Cogito makes things \"easier\", no matter how much you\n> personally believe it, isn't the way everyone feels and is at\n> odds with the native-git message and improvement effort.\n\nIf you disagree about that fact, can you provide some specific\nargumentation?\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\n#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj\n$/=unpack('H*',$_);$_=`echo 16dio\\U$k\"SK$/SM$n\\EsN0p[lN*1\n"},{"id":"294546","messageId":"6efbd9b70611171436t1e0cadf2j7e9387ca77f85538@mail.gmail.com","threadId":"6207","inReplyTo":"20061117213125.GG7201@pasky.or.cz","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Chris Riddoch","fromEmail":"riddochc@gmail.com","sentAt":"2006-11-17T22:36:25Z","receivedAt":"2006-11-17T22:36:25Z","isPatch":false,"sender":{"key":"riddochc@gmail.com","avatar":null},"body":"On 11/17/06, Petr Baudis <pasky@suse.cz> wrote:\n> If someone writes a crash course in pure Git covering the same grounds\n> as the current ones (possibly by just extending/retouching the tutorial)\n> (it does not necessarily need to be a \"refugee\" crash course, it can\n> build up from scratch), I can add it on the web. If it becomes as easy\n> to use and with as mild learning curve as Cogito, it means Cogito got\n> mostly obsolete and I'll happily remove the Cogito crash courses from\n> the web.\n\nAs a relatively new user myself, I ran into the same confusion when I\ncame to the website for the first time.  One of the most prominent\nthings on the front page is the \"Git Crash Courses.\"  Clicking on that\ngives me the crash courses, all of which are about Cogito, not for\nGit.  So why doesn't the front page say \"Cogito Crash Courses\"\ninstead?\n\nAnd I don't think it matters much whether Cogito makes things easier\nor not -- the Git website really should make Git's documentation more\nprominent than Cogito's.  I'd expect the opposite of Cogito's website.\n\nIt *is* unnecessarily confusing.\n\n-- \nepistemological humility\n"},{"id":"294531","messageId":"20061117225037.GI7201@pasky.or.cz","threadId":"6207","inReplyTo":"6efbd9b70611171436t1e0cadf2j7e9387ca77f85538@mail.gmail.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-11-17T22:50:37Z","receivedAt":"2006-11-17T22:50:37Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, Nov 17, 2006 at 11:36:25PM CET, Chris Riddoch wrote:\n> On 11/17/06, Petr Baudis <pasky@suse.cz> wrote:\n> >If someone writes a crash course in pure Git covering the same grounds\n> >as the current ones (possibly by just extending/retouching the tutorial)\n> >(it does not necessarily need to be a \"refugee\" crash course, it can\n> >build up from scratch), I can add it on the web. If it becomes as easy\n> >to use and with as mild learning curve as Cogito, it means Cogito got\n> >mostly obsolete and I'll happily remove the Cogito crash courses from\n> >the web.\n> \n> As a relatively new user myself, I ran into the same confusion when I\n> came to the website for the first time.  One of the most prominent\n> things on the front page is the \"Git Crash Courses.\"  Clicking on that\n> gives me the crash courses, all of which are about Cogito, not for\n> Git.  So why doesn't the front page say \"Cogito Crash Courses\"\n> instead?\n> \n> And I don't think it matters much whether Cogito makes things easier\n> or not -- the Git website really should make Git's documentation more\n> prominent than Cogito's.  I'd expect the opposite of Cogito's website.\n\nI think the difference here is the Git _tool_ vs. the Git version\ncontrol system. Cogito is an element of the second: To use Git, you can\neither use the Git tool or the Cogito tool or the StGIT tool or even\njust the qgit tool (which also lets you inspect the working copy and\ncommit). I believe the tool best suited for general usage by newbies _at\nthis point_ is Cogito, so that's what I use for introduction to Git. I'm\nnot saying this is ideal situation and I and others are/will be working\nto fix it.\n\nI'm all for making it more obvious what's going on at the website, I\nthink the current wording is better. Also, if people believe that a\ncrash course for core Git would help things, I'm all for it as well.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\n#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj\n$/=unpack('H*',$_);$_=`echo 16dio\\U$k\"SK$/SM$n\\EsN0p[lN*1\n"},{"id":"295964","messageId":"BAYC1-PASMTP07F63BC2E5B1D7789E7E57AEE80@CEZ.ICE","threadId":"6207","inReplyTo":"20061117213125.GG7201@pasky.or.cz","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Sean","fromEmail":"seanlkml@sympatico.ca","sentAt":"2006-11-17T23:30:34Z","receivedAt":"2006-11-17T23:30:34Z","isPatch":false,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Fri, 17 Nov 2006 22:31:26 +0100\nPetr Baudis <pasky@suse.cz> wrote:\n\n\n> It's not about documentation but ease to use. I agree and sympathise\n> very much with the effort of making core Git more easy to use and\n> obsoleting Cogito, but until it gets there we should have what's nicest\n> to the users.\n\nAs some new users have already tried to tell you, it's confusing for\n_them_ when they're trying to learn Git to be confronted with Cogito\ndocumentation.  \n\nThe way we're going to get Git to be better is to expose new people\nto it and respond to their comments, complaints and ideas about how\nto make it better and easier to understand as they get up to speed.\nHaving Cogito plastered all over the Git website as the _easy_ \nalternative is counterproductive to that effort.  We need fresh\nblood looking at the Git documentation and trying to learn Git.\n\nBy using the GIT webpage to promote Cogito as the \"easy\" alternative\nyou make it look like the entire GIT community is recommending\nnew users should use Cogito instead.  That does not represent\nthe views of the entire GIT community.  You should be very careful\nto represent the entire community in your role as GIT webmaster.\n\nIf people go to a Cogito website, _that's_ where they should learn\nabout your opinions about why someone should use Cogito in\nplace of Git.  Cogito isn't \"nicest\" for users who don't need\nits extra functionality, or for getting new users involved in\nthe improvement effort of native Git.\n\n"},{"id":"30761","messageId":"20070103170411.GB5491@thunk.org","threadId":"6207","inReplyTo":"20061116221701.4499.qmail@science.horizon.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-01-03T17:04:11Z","receivedAt":"2007-01-03T17:04:11Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Thu, Nov 16, 2006 at 05:17:01PM -0500, linux@horizon.com wrote:\n> I know it took me a while to get used to playing with branches, and I\n> still get nervous when doing something creative.  So I've been trying\n> to get more comfortable, and wrote the following to document what I've\n> learned.\n\nWhat ever happened to this document?  There was some talk of getting\nthis integrated into the git tree as Docmentation/tutorial-3.txt.\nIMHO it would be really, really good to do this before 1.5.0, since I\nthink a lot of users would find it really useful.  Some of the text\nmay need to be moved to other locations, but it might go faster if we\nget the base document into the tree first, and then we can submit\npatches to move text around to integrate it into the other\ndocumentation files.\n\nI'm certainly willing to help out submitting patches to improve the\ndocumentation, and I think this would be a big step towards helping\nnew users to git become much more quickly proficient.\n\n\t\t\t\t\t\t- Ted\n"},{"id":"30762","messageId":"7v1wmcox5w.fsf@assigned-by-dhcp.cox.net","threadId":"6207","inReplyTo":"20070103170411.GB5491@thunk.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-01-03T17:08:43Z","receivedAt":"2007-01-03T17:08:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Theodore Tso <tytso@mit.edu> writes:\n\n> On Thu, Nov 16, 2006 at 05:17:01PM -0500, linux@horizon.com wrote:\n>> I know it took me a while to get used to playing with branches, and I\n>> still get nervous when doing something creative.  So I've been trying\n>> to get more comfortable, and wrote the following to document what I've\n>> learned.\n>\n> What ever happened to this document?  There was some talk of getting\n> this integrated into the git tree as Docmentation/tutorial-3.txt.\n> IMHO it would be really, really good to do this before 1.5.0, since I\n> think a lot of users would find it really useful.\n\nSeconded.  Can I have the latest round?\n"},{"id":"30797","messageId":"20070104052829.15254.qmail@science.horizon.com","threadId":"6207","inReplyTo":"7v1wmcox5w.fsf@assigned-by-dhcp.cox.net","subject":"Re: [DRAFT] Branching and merging with git","fromName":"","fromEmail":"linux@horizon.com","sentAt":"2007-01-04T05:28:29Z","receivedAt":"2007-01-04T05:28:29Z","isPatch":false,"sender":{"key":"linux@horizon.com","avatar":null},"body":"> Seconded.  Can I have the latest round?\n\nUh... can it wait a day or two?  I'm leaving for a camping trip\ntomorrow and won't have much keyboard access...\n\nSorry about that.\n"},{"id":"30798","messageId":"7vbqlfnwxw.fsf@assigned-by-dhcp.cox.net","threadId":"6207","inReplyTo":"20070104052829.15254.qmail@science.horizon.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-01-04T06:11:07Z","receivedAt":"2007-01-04T06:11:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"linux@horizon.com writes:\n\n>> Seconded.  Can I have the latest round?\n>\n> Uh... can it wait a day or two?  I'm leaving for a camping trip\n> tomorrow and won't have much keyboard access...\n\nNo worries.  Have fun.\n"},{"id":"31087","messageId":"20070107234411.GD18009@fieldses.org","threadId":"6207","inReplyTo":"20070103170411.GB5491@thunk.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-07T23:44:11Z","receivedAt":"2007-01-07T23:44:11Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Wed, Jan 03, 2007 at 12:04:11PM -0500, Theodore Tso wrote:\n> What ever happened to this document?  There was some talk of getting\n> this integrated into the git tree as Docmentation/tutorial-3.txt.\n\nJust to throw more fuel on the fire....\n\nI have a draft attempt at a complete \"git user's manual\" at\n\n\thttp://www.fieldses.org/~bfields/\n\nThe goals are:\n\n\t- Readable from beginning to end in order without having read\n\t  any other git documentation beforehand.\n\t- Helpful section names and cross-references, so it's not too\n\t  hard to skip around some if you need to.\n\t- Organized to allow it to grow much larger (unlike the\n\t  tutorials)\n\nIt's more liesurely than tutorial.txt, but tries to stay focused on\npractical how-to stuff.  It adds a discussion of how to resolve merge\nconflicts, and partial instructions on setting up and dealing with a\npublic repository.\n\nI've lifted a little bit from \"branching and merging\" (e.g., some of the\ndiscussion of history diagrams), and could probably steal more if that's\nOK.  (Similarly anyone should of course feel free to reuse bits of this\nif any parts seem more useful than the whole.)\n\nThere's a lot of detail on managing branches and using git-fetch, just\nbecause those are essential even to people needing read-only access\n(e.g., kernel testers).  I think those sections will be much shorter\nonce the new \"git remote\" command and the disconnected checkouts are\ntaken into account.\n\nI do feel bad about adding yet another piece of documentation, but I we\nneed something that goes through all the basics in a logical order, and\nI wasn't seeing how to grow the tutorials into that.\n\nOpinions?\n\n--b.\n"},{"id":"31089","messageId":"7vzm8uz7pz.fsf@assigned-by-dhcp.cox.net","threadId":"6207","inReplyTo":"20070107234411.GD18009@fieldses.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-01-08T00:24:08Z","receivedAt":"2007-01-08T00:24:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> writes:\n\n> I do feel bad about adding yet another piece of documentation, but I we\n> need something that goes through all the basics in a logical order, and\n> I wasn't seeing how to grow the tutorials into that.\n>\n> Opinions?\n\nI was having the feeling that we need to start over the\ndocumentation from a clean slate by first coming up with a\ncoherent presentation order and then filling sections in it,\ninstead of tweaking existing documents here and there.  The\nexisting documents were written in different development stages\nof git, and each document tries to be more or less independent\nfrom others in the area it wants to talk about, and reading all\nof them in _any_ order is not the best way to learn git because\nof duplication.  Also I suspect some information in older\ndocuments, while being still valid and technically correct,\npredates invention of a better/simpler alternative.\n\nIn other words, I think we have enough information in the\ntutorial documents, but the problem is not the lack of\ninformation -- the problem is the lack of organization.\n\nI think this effort of yours is wonderful because it directly\ntackles that problem.\n"},{"id":"31091","messageId":"20070108004006.GB23182@thunk.org","threadId":"6207","inReplyTo":"20070107234411.GD18009@fieldses.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-01-08T00:40:06Z","receivedAt":"2007-01-08T00:40:06Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Sun, Jan 07, 2007 at 06:44:11PM -0500, J. Bruce Fields wrote:\n> On Wed, Jan 03, 2007 at 12:04:11PM -0500, Theodore Tso wrote:\n> > What ever happened to this document?  There was some talk of getting\n> > this integrated into the git tree as Docmentation/tutorial-3.txt.\n> \n> Just to throw more fuel on the fire....\n> \n> I have a draft attempt at a complete \"git user's manual\" at\n> \n> \thttp://www.fieldses.org/~bfields/\n\nIs that the right URL?  That gets me to \"Not Bruce's Webpage\" and I\ndon't see an obvious link to git documentation...\n\n\t\t\t\t\t\t- Ted\n"},{"id":"31092","messageId":"20070108004641.GG18009@fieldses.org","threadId":"6207","inReplyTo":"20070108004006.GB23182@thunk.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-08T00:46:41Z","receivedAt":"2007-01-08T00:46:41Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Sun, Jan 07, 2007 at 07:40:06PM -0500, Theodore Tso wrote:\n> On Sun, Jan 07, 2007 at 06:44:11PM -0500, J. Bruce Fields wrote:\n> > On Wed, Jan 03, 2007 at 12:04:11PM -0500, Theodore Tso wrote:\n> > > What ever happened to this document?  There was some talk of getting\n> > > this integrated into the git tree as Docmentation/tutorial-3.txt.\n> > \n> > Just to throw more fuel on the fire....\n> > \n> > I have a draft attempt at a complete \"git user's manual\" at\n> > \n> > \thttp://www.fieldses.org/~bfields/\n> \n> Is that the right URL?  That gets me to \"Not Bruce's Webpage\" and I\n> don't see an obvious link to git documentation...\n\nCrap:\n\n\thttp://www.fieldses.org/~bfields/git-user-manual.html\n\nSorry about that.--b.\n"},{"id":"31097","messageId":"ens6ci$ga9$1@sea.gmane.org","threadId":"6207","inReplyTo":"20070108004641.GG18009@fieldses.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-01-08T01:22:35Z","receivedAt":"2007-01-08T01:22:35Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"J. Bruce Fields wrote:\n\n> On Sun, Jan 07, 2007 at 07:40:06PM -0500, Theodore Tso wrote:\n>> On Sun, Jan 07, 2007 at 06:44:11PM -0500, J. Bruce Fields wrote:\n>>> \n>>> I have a draft attempt at a complete \"git user's manual\" at\n>>> \n>>>     http://www.fieldses.org/~bfields/\n>> \n>> Is that the right URL?  That gets me to \"Not Bruce's Webpage\" and I\n>> don't see an obvious link to git documentation...\n> \n> Crap:\n> \n>       http://www.fieldses.org/~bfields/git-user-manual.html\n\nAdded to\n  http://git.or.cz/gitwiki/GitDocumentation\n  http://git.or.cz/gitwiki/GitLinks\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"31108","messageId":"20070108023511.GI18009@fieldses.org","threadId":"6207","inReplyTo":"7vzm8uz7pz.fsf@assigned-by-dhcp.cox.net","subject":"Re: [DRAFT] Branching and merging with git","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-08T02:35:11Z","receivedAt":"2007-01-08T02:35:11Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Sun, Jan 07, 2007 at 04:24:08PM -0800, Junio C Hamano wrote:\n> \"J. Bruce Fields\" <bfields@fieldses.org> writes:\n> In other words, I think we have enough information in the\n> tutorial documents, but the problem is not the lack of\n> information -- the problem is the lack of organization.\n> \n> I think this effort of yours is wonderful because it directly\n> tackles that problem.\n\nOK, thanks for the vote of confidence....  My tentative organization\n(which I'm totally open to argument about) is:\n\nchapters 1 and 2: \"Read-only\" operations:\n\n\tclone, fetch, the commit DAG, etc.; material that could be\n\tuseful to a linux kernel tester, for example.  This also\n\tincludes lots of stuff about branch manipulation and fetching,\n\tjust because that's necessary to keep a repo up to date and\n\tcheck out random commits.  Once we have \"git remote\" and\n\tdisconnected checkouts most of this could be postponed till\n\tlater.\n\nChapter 3: \"Read-write\" operations:\n\n\tRead-write stuff: creating commits (basic mention of index),\n\thandling merges, git-gc, ending with distributed stuff:\n\timporting and exporting patches, pull and push, etc.\n\nChapter 4 (unwritten): interactions with other VCS's\n\n\tcvs, subversion.  Also some of us use track projects with git\n\teven when all we've got is a sequence of release tarballs to\n\ttrack, and that might be worth documenting.\n\nChapter 5 (unwritten): rewriting history\n\n\trebasing, cherry-picking, managing patch series, etc.\n\nChapter 6 (unwritten): git internals\n\n\tI intend to just do a wholesale import of either tutorial-2.txt,\n\tcore-tutorial.txt, or the README, or some combination thereof,\n\tbut can't decide which.\n\n--b.\n"},{"id":"31130","messageId":"8b65902a0701080438v4822eabdi135a5358f977328a@mail.gmail.com","threadId":"6207","inReplyTo":"20070108004641.GG18009@fieldses.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Guilhem Bonnefille","fromEmail":"guilhem.bonnefille@gmail.com","sentAt":"2007-01-08T12:38:19Z","receivedAt":"2007-01-08T12:38:19Z","isPatch":false,"sender":{"key":"guilhem.bonnefille@gmail.com","avatar":"https://gravatar.com/avatar/375364bfee1f61197c540e37465abe3619fc24eb3a36b0edcea7f15b124036b0?d=mp&s=160"},"body":"On 1/8/07, J. Bruce Fields <bfields@fieldses.org> wrote:\n> On Sun, Jan 07, 2007 at 07:40:06PM -0500, Theodore Tso wrote:\n> > On Sun, Jan 07, 2007 at 06:44:11PM -0500, J. Bruce Fields wrote:\n> > > On Wed, Jan 03, 2007 at 12:04:11PM -0500, Theodore Tso wrote:\n> > > > What ever happened to this document?  There was some talk of getting\n> > > > this integrated into the git tree as Docmentation/tutorial-3.txt.\n> > >\n> > > Just to throw more fuel on the fire....\n> > >\n> > > I have a draft attempt at a complete \"git user's manual\" at\n> > >\n> > >     http://www.fieldses.org/~bfields/\n> >\n> > Is that the right URL?  That gets me to \"Not Bruce's Webpage\" and I\n> > don't see an obvious link to git documentation...\n>\n> Crap:\n>\n>         http://www.fieldses.org/~bfields/git-user-manual.html\n\nNice work.\n\nMy only 2 cents: the SVN book is really a good book, as it contains\nboth simple user and advanced hacker info. As it is in free licence,\nperhaps it could be possible to \"port\" the book to Git. I saw that the\nSVK book is such a port. But it's a DocBook document.\nhttp://svnbook.red-bean.com/\n-- \nGuilhem BONNEFILLE\n-=- #UIN: 15146515 JID: guyou@im.apinc.org MSN: guilhem_bonnefille@hotmail.com\n-=- mailto:guilhem.bonnefille@gmail.com\n-=- http://nathguil.free.fr/\n"},{"id":"31133","messageId":"87d55pr7o3.fsf@morpheus.local","threadId":"6207","inReplyTo":"20070108023511.GI18009@fieldses.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-01-08T13:04:44Z","receivedAt":"2007-01-08T13:04:44Z","isPatch":false,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> writes:\n\n> OK, thanks for the vote of confidence....  My tentative organization\n> (which I'm totally open to argument about) is:\n>\n> chapters 1 and 2: \"Read-only\" operations:\n\n> Chapter 3: \"Read-write\" operations:\n\n> Chapter 4 (unwritten): interactions with other VCS's\n\nI think this should be considered more peripheral, since it is really\nan independent piece, and nobody needs to read it to learn how git\nworks.  So I would probably move it to the end.\n\n> Chapter 5 (unwritten): rewriting history\n\n> Chapter 6 (unwritten): git internals\n\n\n-- \nDavid Kågedal\n"},{"id":"31144","messageId":"20070108140305.GE32756@thunk.org","threadId":"6207","inReplyTo":"20070108023511.GI18009@fieldses.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-01-08T14:03:05Z","receivedAt":"2007-01-08T14:03:05Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Sun, Jan 07, 2007 at 09:35:11PM -0500, J. Bruce Fields wrote:\n> chapters 1 and 2: \"Read-only\" operations:\n> \n> \tclone, fetch, the commit DAG, etc.; material that could be\n> \tuseful to a linux kernel tester, for example.  This also\n> \tincludes lots of stuff about branch manipulation and fetching,\n> \tjust because that's necessary to keep a repo up to date and\n> \tcheck out random commits.  Once we have \"git remote\" and\n> \tdisconnected checkouts most of this could be postponed till\n> \tlater.\n\nI would add a QuickStart Chapter before you start going into the\n\"read-only\" oeperations.  It would show how to create a completely\nempty repository, and add a few commits.  It would also demonstrate\nhow to clone an example repository (with a fixed set of contents,\nstored at git://git.kernel.org/pub/scm/git/example and add a commit\nusing \"git commit -a\".\n\nThe basic idea is to show the user that git really isn't that hard,\n*before* you start diving into a lot of details.  If you don't tell a\nuser how to make a commit until Chapter 3, he/she will assume it's\nbecause it's Really Hard, and you may end up losing them before that.\n\n> Chapter 3: \"Read-write\" operations:\n> \n> \tRead-write stuff: creating commits (basic mention of index),\n> \thandling merges, git-gc, ending with distributed stuff:\n> \timporting and exporting patches, pull and push, etc.\n\nAt least some discussions of branches needs to happen here; it's\nreally important to talk about different workflows, and how you use\nbranches as part of your read-write operations.  Some folks might or\nmight not use topic branches, but the concept of using temporary\nbranches to try things out is critical.\n\n> Chapter 4 (unwritten): interactions with other VCS's\n> \n> \tcvs, subversion.  Also some of us use track projects with git\n> \teven when all we've got is a sequence of release tarballs to\n> \ttrack, and that might be worth documenting.\n> \n> Chapter 6 (unwritten): git internals\n> \n> \tI intend to just do a wholesale import of either tutorial-2.txt,\n> \tcore-tutorial.txt, or the README, or some combination thereof,\n> \tbut can't decide which.\n\nYou might want to consider putting these two chapters into appendices.\n\n\t\t\t\t\t\t- Ted\n"},{"id":"31181","messageId":"20070109024125.GD1686@fieldses.org","threadId":"6207","inReplyTo":"20070108140305.GE32756@thunk.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-09T02:41:26Z","receivedAt":"2007-01-09T02:41:26Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Mon, Jan 08, 2007 at 09:03:05AM -0500, Theodore Tso wrote:\n> I would add a QuickStart Chapter before you start going into the\n> \"read-only\" oeperations.  It would show how to create a completely\n> empty repository, and add a few commits.  It would also demonstrate\n> how to clone an example repository (with a fixed set of contents,\n> stored at git://git.kernel.org/pub/scm/git/example and add a commit\n> using \"git commit -a\".\n>\n> The basic idea is to show the user that git really isn't that hard,\n> *before* you start diving into a lot of details.  If you don't tell a\n> user how to make a commit until Chapter 3, he/she will assume it's\n> because it's Really Hard, and you may end up losing them before that.\n\nYeah, I agree.  I just haven't been able to decide quite what to choose\nfor that purpose.  Some choices:\n\n\t- We could just pare down the tutorial a bit and drag it in as\n\t  chapter one.\n\n\t- I tried writing something modeled loosely on the hg quick\n\t  start.  It's a little out of date now, but that could be\n\t  fixed:\n\n\t\thttp://www.fieldses.org/~bfields/git-quick-start.html\n\n\t- Or maybe a revised everyday.txt would do the job?\n\nAny opinions?\n\n> At least some discussions of branches needs to happen here;\n\nThe basic nuts-and-bolts (how to create and delete branches, etc.)\nshould all be covered, of course, but....\n\n> it's really important to talk about different workflows, and how you\n> use branches as part of your read-write operations.  Some folks might\n> or might not use topic branches, but the concept of using temporary\n> branches to try things out is critical.\n\n.... Maybe it'd be fun to have a section called just \"examples\" at the\nend of each chapter.  The sort of thing you're describing could fit in\nwell there.  I'd need some help collecting interesting examples.\n\n--b.\n"},{"id":"31188","messageId":"20070109041751.GE1686@fieldses.org","threadId":"6207","inReplyTo":"8b65902a0701080438v4822eabdi135a5358f977328a@mail.gmail.com","subject":"Re: [DRAFT] Branching and merging with git","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-09T04:17:51Z","receivedAt":"2007-01-09T04:17:51Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Mon, Jan 08, 2007 at 01:38:19PM +0100, Guilhem Bonnefille wrote:\n> Nice work.\n\nThanks!\n\n> My only 2 cents: the SVN book is really a good book, as it contains\n> both simple user and advanced hacker info. As it is in free licence,\n> perhaps it could be possible to \"port\" the book to Git. I saw that the\n> SVK book is such a port. But it's a DocBook document.\n> http://svnbook.red-bean.com/\n\nThanks, yes, that does look very polished.\n\nIf there's any part you'd be particularly interested in seeing \"ported\",\nI'd be happy to help incorporate your work.\n\n--b.\n"},{"id":"31213","messageId":"45A3564E.7080003@op5.se","threadId":"6207","inReplyTo":"20070109024125.GD1686@fieldses.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2007-01-09T08:46:06Z","receivedAt":"2007-01-09T08:46:06Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"J. Bruce Fields wrote:\n> On Mon, Jan 08, 2007 at 09:03:05AM -0500, Theodore Tso wrote:\n>> I would add a QuickStart Chapter before you start going into the\n>> \"read-only\" oeperations.  It would show how to create a completely\n>> empty repository, and add a few commits.  It would also demonstrate\n>> how to clone an example repository (with a fixed set of contents,\n>> stored at git://git.kernel.org/pub/scm/git/example and add a commit\n>> using \"git commit -a\".\n>>\n>> The basic idea is to show the user that git really isn't that hard,\n>> *before* you start diving into a lot of details.  If you don't tell a\n>> user how to make a commit until Chapter 3, he/she will assume it's\n>> because it's Really Hard, and you may end up losing them before that.\n> \n> Yeah, I agree.  I just haven't been able to decide quite what to choose\n> for that purpose.  Some choices:\n> \n> \t- We could just pare down the tutorial a bit and drag it in as\n> \t  chapter one.\n> \n> \t- I tried writing something modeled loosely on the hg quick\n> \t  start.  It's a little out of date now, but that could be\n> \t  fixed:\n> \n> \t\thttp://www.fieldses.org/~bfields/git-quick-start.html\n> \n\nI like this, although fetch should probably have \"--force\" instead of \nthe \"+branch\" notation. --force stands out more and users are familiar \nwith --force possibly destroying things (rm -rf, anyone?).\n\n> \t- Or maybe a revised everyday.txt would do the job?\n> \n> Any opinions?\n> \n\nI think the document is fine as it is, but could probably start off with \na link to the tutorial, quickstart or a revised version of everyday.txt, \nstating that \"here's something you might want to read if you prefer to \nexperiment. If you think something goes wrong, come back here and find \nout why\".\n\n>> At least some discussions of branches needs to happen here;\n> \n> The basic nuts-and-bolts (how to create and delete branches, etc.)\n> should all be covered, of course, but....\n> \n\nI found it quite sufficient. Perhaps it would be nice to include some \nmore advanced examples, like octopus merges and things like that, \nalthough I feel such things could well live in an appendix to keep all \nthe easy operations up front. Most people I know will most likely \n*never* use octopus merges. 90% of the merges we do here at work result \nin fast-forwards, so a real merge is already considered a bit odd.\n\n>> it's really important to talk about different workflows, and how you\n>> use branches as part of your read-write operations.  Some folks might\n>> or might not use topic branches, but the concept of using temporary\n>> branches to try things out is critical.\n> \n> .... Maybe it'd be fun to have a section called just \"examples\" at the\n> end of each chapter.  The sort of thing you're describing could fit in\n> well there.  I'd need some help collecting interesting examples.\n> \n\nIndeed. I for one like examples that tell me\n\n# type this\n# this will happen\n# you can see what you just did with this, this, and this command\n# this is because...\n\nNot only is it good for learning the how and the why, but it also trains \nthe fingers right from the start. Hopefully the UI is stabilized enough \nby now that we can reliably tell users how to accomplish a certain \nthing. UI changes must almost certainly be listed at whatever official \nsite git has. As Junio has already pointed out, the members of the git \nmailing list are now in minority among the git users, so some other \nplace has to hold the user-visible changes as well and the location of \nthat site must probably be published along with the tools.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"31251","messageId":"20070109154900.GA17179@fieldses.org","threadId":"6207","inReplyTo":"45A3564E.7080003@op5.se","subject":"Re: [DRAFT] Branching and merging with git","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-09T15:49:00Z","receivedAt":"2007-01-09T15:49:00Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Tue, Jan 09, 2007 at 09:46:06AM +0100, Andreas Ericsson wrote:\n> J. Bruce Fields wrote:\n> >\t- I tried writing something modeled loosely on the hg quick\n> >\t  start.  It's a little out of date now, but that could be\n> >\t  fixed:\n> >\n> >\t\thttp://www.fieldses.org/~bfields/git-quick-start.html\n> >\n> \n> I like this, although fetch should probably have \"--force\" instead of \n> the \"+branch\" notation. --force stands out more and users are familiar \n> with --force possibly destroying things (rm -rf, anyone?).\n\nI started out writing it that way (for the reasons you give), then\nchanged it on the theory starting out with the \"+\" notation would make\nit simpler explaining how to do the remote configuration.\n\nNow that there's git-remote, and less need to manipulate the remote\nconfiguration by hand, maybe that's less important.\n\n> I think the document is fine as it is, but could probably start off with \n> a link to the tutorial, quickstart or a revised version of everyday.txt, \n> stating that \"here's something you might want to read if you prefer to \n> experiment. If you think something goes wrong, come back here and find \n> out why\".\n\nSounds sensible.\n\n> Indeed. I for one like examples that tell me\n> \n> # type this\n> # this will happen\n> # you can see what you just did with this, this, and this command\n> # this is because...\n> \n> Not only is it good for learning the how and the why, but it also trains \n> the fingers right from the start.\n\nOK.  This is a place where I'd really appreciate any contributions.\n\n--b.\n"},{"id":"31259","messageId":"20070109165828.GB9153@thunk.org","threadId":"6207","inReplyTo":"45A3564E.7080003@op5.se","subject":"Re: [DRAFT] Branching and merging with git","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-01-09T16:58:28Z","receivedAt":"2007-01-09T16:58:28Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Tue, Jan 09, 2007 at 09:46:06AM +0100, Andreas Ericsson wrote:\n> I think the document is fine as it is, but could probably start off with \n> a link to the tutorial, quickstart or a revised version of everyday.txt, \n> stating that \"here's something you might want to read if you prefer to \n> experiment. If you think something goes wrong, come back here and find \n> out why\".\n\nIf what we're going to do is a \"git user's manual\", I'd recommend\nkeeping the 2-3 pages in the manual, and do it via a link to some\nother document.  One of the issues with the git documentation is that\nit's *too* branchy, and some the branches go off to some truly scary\nlow-level implementation detail.  If we are going to assume that isn't\ngoing to change (and I am glad that the low-level details are\ndocumented, and am not advocating that they be deleted), then keeping\na user-friendly QuickStart in the main document might not be a bad\ndecision.\n\n\t\t\t\t\t\t- Ted\n"},{"id":"31358","messageId":"20070110041517.GC25265@fieldses.org","threadId":"6207","inReplyTo":"20070109165828.GB9153@thunk.org","subject":"Re: [DRAFT] Branching and merging with git","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-01-10T04:15:17Z","receivedAt":"2007-01-10T04:15:17Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Tue, Jan 09, 2007 at 11:58:28AM -0500, Theodore Tso wrote:\n> If what we're going to do is a \"git user's manual\", I'd recommend\n> keeping the 2-3 pages in the manual, and do it via a link to some\n> other document.  One of the issues with the git documentation is that\n> it's *too* branchy, and some the branches go off to some truly scary\n> low-level implementation detail.  If we are going to assume that isn't\n> going to change (and I am glad that the low-level details are\n> documented, and am not advocating that they be deleted), then keeping\n> a user-friendly QuickStart in the main document might not be a bad\n> decision.\n\nSounds reasonable.\n\nI'll probably set this aside a few days, then do some more work on it\nthis weekend.  (Patches welcomed, though--source is in the master branch\nof git://linux-nfs.org/~bfields/git.git.)\n\n--b.\n"}]}