Hi Yegappan,
after a friend saw your message over here, he told: "OMG, this is
hopeless, don't try…". But here am I trying, because I've seen your
confusion many times in the past, and it's not a cheatsheet that can
help you, it's better understanding how distributed VCS (and git more
specifically) works. I hope the following will help you.
On Sun, May 29, 2016 at 06:06:12PM -0700, Yegappan Lakshmanan wrote:
> On Sun, May 29, 2016 at 12:59 PM, 'Guyzmo' via vim_dev
> <
vim...@googlegroups.com> wrote:
> > <strikes this>
> >> $ cd <some-directory>
> >> $ git clone
https://github.com/<your-name>/vim/vim.git
> > </strikes this>
> >
> > a. you already got a fork that you've cloned locally, so why make
> > another clone?
> I prefer to use separate directories for each feature/bug fix development.
> For each directory, I start with cloning the Vim repository.
Well, then you're missing the point of using a tool such as git. Yes,
it's needing from you to get out of your comfort zone, but using
separate directories for different branches is just plain wrong.
For example, let's say you start a feature branch X to implement a
feature. Along the way, you discover a bug Y in the code. Then you
create a patch, but it's in your current workspace which is within
branch X!
What would you do then? Go create a new directory for a new branch and
then copy/paste the lines of the patch? But if that patch is scattered
over 20 files, one line for each, then you spend half a day doing it?
If you're having a single workspace, you just create that commit into a
new branch that you'll call Y, that you rebase onto the master, and then
you can push it, and make it a new pull request, and eventually it will
land into the upstream's master before you've finished your feature X,
and you can rebase X onto upstream/master which will include Y.
And voila. All that happening without disrupting your coding flow for
the feature X, and without having a gazillion directories around.
A branch is a first class citizen you should embrace with git, and not
workaround, I know it's hard when you're new to that, but don't work
against the gymnastic, embrace it.
[…]
> >> Pulling in latest changes from master
> > <strikes this>
> >> $ git stash
> >> $ git pull
> >> $ git stash pop
> > </strikes this>
> >
> > Well that one is confusing for whoever read this, and I guess you're
> > confused about it. A pull is `git fetch` followed by a `git rebase`.
> >
> > So instead of stashing your changes, you should:
> >
> > % git fetch --all
>
> What will happen to the changes in the local directory? Will the above
> command overwrite all the local changes or will it automatically
> merge the changes?
The pull command is confusing because it's doing two things at once, and
truth is, a git newbie should never use it. So please, forget that pull
even exists (at least until you're comfortable with git).
From the `git help fetch` page:
git-fetch - Download objects and refs from another repository<Paste>
So all it does is fetching the branches from all your remote
repositories. To be clear on what it does, understand that within your
workspace, there's local branches and remote branches. The local
branches are the one you've explicitely created (like master or X, Y, Z
for each feature/bugfix you want to work on).
But there's also the "remote" branches that you've fetched (when you do
a git fetch or a git pull, or even a git clone). So let's say you did:
% git clone
https://github.com/vim/vim.git
it has created a remote called "origin" and two branches "origin/master" and "master":
% git remote
origin
% git branch --all
master
origin/master
So when you do 'git fetch origin' it will look at all the branches that
belong to the remote "origin", and update them with the new commits from
the remote repository. Then, when you make a "fork" of the project on
your github, you do:
% git remote add github g...@github.com:your-name/vim
% git fetch --all
that will create a new master branch, which will be on the github remote:
% git branch --all
master
origin/master
github/master
so then you'll have three master branch in your local repository, and
it's up to you to decide with which one your local master is in sync
with. (here you can see why I prefer to call the "origin" remote
"upstream", as they both are on github and leaves less room for
confusion).
So to answer very directly to your question:
> What will happen to the changes in the local directory?
Nothing, it's only updating the "remote" branches, in our current
example that will be origin/master and github/master.
> Will the above command overwrite all the local changes or will it
> automatically merge the changes?
Neither, as it's doing nothing ! It's then up to you to choose what you
want to do. You can either choose to:
% git merge origin/master
which will create a merge commit (and in visualisation an arrow from
"origin/master" onto your branch).
% git rebase origin/master
Which will reprocess all your local commits, so they sit on top of the
new master.
Then which strategy should you choose depends on your development
process. Usually, rebasing is the best choice while your branch is not
public, and merging is the best choice as soon as you start working with
others on your branch. And eventually you'll find yourself doing a bit
of both.
As a conclusion to that, as you're new to git, always use a graphical
representation of your repository (using tig, gitg, git-cola, gitxr,
sourcetree, or whatever else…), so you can visualize what you're doing
with commits, branches, remotes etc..
I still am today using those when I'm doing complex branch stuff, to
always feel safe about what I'm doing, even if I know damn well what I'm
doing.
And also remember that you *NEVER* loose commits with git (except in
some rare conditions, like force running the garbage collector). Read
some tutorials about "reflog" on how you can save yourself from a major
branching mayhem or merging chaos.
Happy vimming, and happy gitting,
--
Guyzmo