I am a user of SVN and now I am learning Git.
In SVN I usually checkout on my local machine a repo, which includes all branches in my project and I used to select the folder for my branch I am interested to and work there.
I see a difference using Git.
Currently I am cloning a repo and clone a specific branch using gitk.
The project folder contains only the content for that branch and I cannot see all branches as in SVN, which is a little confusing for me.
I cannot find an easy way to see all branches in my local repository using Git.
-
I would like to know if the Git process I described is "standard" and some how correct or I am missing something.
-
Also I would like to know how to handle a process where I need to work on two branches at the same time in case, for example, I need to make an hotfix on master but keep the content of another branch too.
-
What is a recommend name conventions to make the folders which include the branch cloned from the repo in Git, example
myproject-branchname
?
Best Answer
Welcome to the gang!
SVN Re-education
Hold on for a moment. While CVS and SVN and other traditional (i.e. centralized) version control system fulfill (mostly) the same purpose as modern (i.e. distributed) version control systems like mercurial and Git, you'll be much better off learning Git from the ground up instead of trying to transfer your SVN workflow to Git.
http://hginit.com (view on archive.org) by Joel Spolsky (one of the very founders of Stack Exchange) is a tutorial for mercurial, not Git, but it's zero-th chapter, "Subversion Re-education" is useful for people switching away from SVN to any distributed version control system, as it tells you what SVN concepts you have to (temporarily) un-learn (or to
stash
away, as Git users might say) to be able wrap your head around the distributed version control system concepts and the idiomatic workflows established to work with them.So you can read that zero-th chapter and mostly just replace the word "mercurial" with "Git" and thereby properly prepare yourself and your mind for Git.
The fine print
(You might skip this for now.) While mercurial and Git are much more similar to each other than to SVN, there are some conceptual differences between them, so some of the statements and advice in "Subversion Re-education" will become technically wrong when replacing "mercurial" with "Git":
In SVN, everything is a directory (but you shouldn't necessarily treat it as such)
But I've been interrupting you. You were saying?
If, by that, you mean you've checked out the SVN repository's root folder (or any other folder corresponding to more than to
trunk
or to a single branch, e.g. in the conventional SVN repo layout thebranches
folder containing all non-trunk branches) then I dare say you've probably used SVN wrong(ish), or at least abused a bit the fact that trunk, branches and tags are all folded into a single (though hierarchical) namespace together with directories within the revisions/codebase.While it might be tempting to change several SVN branches in parallel, that is AFAIK not how SVN is intended to be used. (Though I'm unsure about what specific downsides working like that might have.)
In Git, only directories are directories
Every clone of a Git repository is itself a Git repository: By default, it gets a full copy of the origin repository's history, including all revisions, branches and tags. But it will keep all that our of your way: Git stores it in a file-based database of sorts, located in the repository's root folder's hidden
.git/
subfolder.But what are the non-hidden files you see in the repository folder?
When you
git clone
a repository, Git does several things. Roughly:.git/
subfolder with the "database"master
).That last step means that Git looks up the revision that this branch points at, and unpacks the file-tree stored there (the database uses some means of compression and de-duplication) into the repository's root folder. That root folder and all its subfolders (excluding the special
.git
subfolder) are known as your repository's "working copy". That's where you interact with the content of the currently checked-out revision/branch. They're just normal folders and files. However, to interact with the repository per-se (the "database" of revisions and references) you usegit
commands.Seeing Git branches and interacting with Git branches
The version of
gitk
I got cannot clone repositories. It can only view repo history and create branches and check out branches. Also, there's no "cloning" a branch. You can only clone repositories.Did you mean you clone a repo using
git clone ...
and then, usinggitk
, check out a branch?Yes, that is pretty standard:
git clone ...
git checkout ...
or using a graphical tool likegikt
Maybe:
git branch
git branch -r
or all branches withgit branch -a
you can use
gitk
to view the complete history (all branches tags etc. that your local repo knows about) by invoking it withHow to work with multiple branches in parallel
There's different scenarios here:
A new (yet to be created) change needs to be applied to multiple branches
Use this workflow:
c
from a revision that already is in the ancestry of all these branches (e.g. the revision that introduced the bug when the change will be a bugfix) or from a revision that (including all its ancestors) is acceptable to be introduced in all these branches.c
.For each branch
b
that needs the change:Check out
b
:Merge
c
intob
:Remove branch
c
:An existing change is needed on a different branch
(... but without the other changes made on the where that change resides)
On one branch
a
, you want to change one or some files to the exact state they have on a different branchb
a
Get the file contents from branch
b
:(Other than
git checkout
without passing paths, this won't switch to branchb
, only get the requested file contents from there. These files might or might not already exist ona
. If they do, they're overwritten with their content onb
.)While working on one branch, you want to look at how things are on another branch
Check out the branch you want to work on.
Then, for looking at the other branch,
gitk
try to switch the radio buttons from "patch" to "tree")git worktree
to create a separate working directory of the same repository (i.e. also using the database in.git/
directory of your current local repository) where you can check out that other branch