"Frank Millman" <fr...@chagford.com> writes: > Hi all > > I know there some Git experts on this list, so I hope you don't mind me > posting this question here. > > I am slowly getting comfortable with Git, but there is something that > confuses me.
If you want to be really comfortable with Git, you need to understand basics of its rather simple underlying data model. Find a toutorial that discusses this, and things will start to take their natural places. You need to become aware that from Git point of view, your project history is a DAG of commits, and branches are just pointers to specific nodes of the DAG. It's very essential, so I repeat: "branch" in Git is nothing more than a named pointer to specific commit in the DAG. You should also learn that the files you are changing constitute "working tree", and working tree does not belong to the DAG (and therefore to any branch). Git simply remembers particular commit in the DAG the working tree is checked-out from in the special HEAD pointer (that usually points to the current branch, that in turn points to the commit). > You are encouraged to make liberal use of 'branches', and if required you > can have multiple branches running concurrently. I'm afraid "multiple branches running concurrently" could be rather confusing. Recalling that Git branches are just pointers, they don't "run", they just exist. One needs to clearly understand the difference between Git branch, being a pointer to a commit, and the sequence of commits that lead to the commit at which Git branch points. When we say "branch of development", we usually mean the latter, and when we run "git checkout <branch_name>" we should understand we mean the former. > When you commit changes on one branch, Strictly speaking, when you commit, you don't commit changes, you create commit that contains entire state of your tree, and then this new commit is attached to the DAG where current branch points to. Then current branch is changed to point to this new commit. > those changes are not visible to other branches Exaclty. Any commit in the DAG is either reachable or not from given branch when history is traversed backwards. That's how "visible" is defined in Git. Right after commit is made, it's only reachable from the current branch (if any) indeed. > until you merge, Exactly. When you merge a branch to another branch, all commits reachable from the "branch" become reachable from "another branch" as well. > so each branch can be worked on independently. > > However, if you are working on a branch and make some changes, those changes > are visible to *all* branches until you commit. No, as they are not in the DAG yet, they are not reachable from any branches, so they are not visible to any of them. What you see are changes in your working tree with respect to the commit that is currently checked-out (usually those one to which the current branch points). > If you run 'git status' from any branch, you can see all files that > have been modified or added. You don't run 'git status' on a branch. You run it from within repository/working tree, and then repository (usually) has some specific branch being current at the time of invokation of 'git status' that 'git status' will report as such. > It seems to me that this can be confusing. When you are ready to commit > changes on one branch, you have to - > - check that it is the currently checked-out branch, which is not always > obvious What exactly "it" means in the "it is the currently..." above? Do you mean you need to check that the current branch is those one you want to commit changes into? If so, ask youself why do you do changes to a state of your working tree that was checked out from any other branch in the first place? Usually, you checkout a branch, make changes and commit them. Only if you realize that you was (and still are) on the wrong branch, you need to switch branches, and Git allows you to take your changes along with you, exactly what you need in this case. If what you want is to temporarily stop working on these particular changes and visit (checkout) another branch, you can stash your changes using "git stash" and restore them later, or you can commit the changes (remember that commits are local unless you publish them), and then, after you return to this branch later, use, e.g., "git reset HEAD~1" to continue editing your changes, or you can just edit further and then commit the changes as the new commit, or amend those temporary commit with your new changes ("git commit --amend"). > - choose which altered files you want to add to the staging area > - stage them and then commit You rather usually choose them by adding them to the staging area (unless we talk about some GUI on top of Git), so it rather looks like: - choose which changes you want to commit by adding them to the staging area. - commit. You can often bypass staging by "git commit -a", but anyway, "staging area" or "index" is yet another thing in Git it's better to make yourself familiar with, as you won't be able to ignore it if you ever reabase or merge. > This seems error-prone. Am I missing something? What exactly is error-prone? Are you afraid to commit to a wrong branch? Are you afraid to commit the changes you didn't want to commit? Anyway, if you did a mistake, you should be able to examine situation and fix it rather easily, provided you didn't yet publish your history. HTH, -- Sergey. -- https://mail.python.org/mailman/listinfo/python-list