Vim git cheat sheet

338 views
Skip to first unread message

Yegappan Lakshmanan

unread,
May 28, 2016, 3:19:33 PM5/28/16
to Vimdev
Hi all,

I was looking for a Git cheat sheet for a Vim developer last week.
I couldn't find one. I have put together the following list of commands
(just in case someone is looking for it in the future).

Fork the Vim repository
1. Fork the Vim repository from the github WebUI
2. Clone the Vim repository:
$ cd <some-directory>
$ git clone https://github.com/<your-name>/vim/vim.git
$ cd vim
3. Configure the upstream branch:
$ git remote add --track master upstream
git://github.com/vim/vim.git
$ git push origin master

Synchronizing a fork with the upstream
$ git checkout master
$ git fetch upstream
$ git rebase upstream/master
$ git push origin master

Creating a branch
1. Clone the Vim repository:
$ cd <some-directory>
$ git clone https://github.com/<your-name>/vim/vim.git
2. Create a child branch for the feature/bug fix:
$ git checkout -b <child-branch-name>
3. Push the new child branch to remote master:
$ git push origin <child-branch-name>

Committing changes to a child branch
1. Commit the changes:
$ git commit -m "Commit comment"
2. Push the changes to the child branch:
$ git push origin <child-branch-name>

Creating a pull request
Go to github.com and create a pull request for the child branch to submit
the changes for merging into the main Vim repository

Synchronizing a branch with the master
$ git checkout master
$ git fetch upstream
$ git rebase upstream/master
$ git checkout <child-branch-name>
$ git rebase master
$ git push --force

Cloning a child branch
$ cd <some-directory>
$ git clone https://github.com/<your-name>/vim/vim.git
$ git checkout <child-branch-name>

Pulling in latest changes from master
$ git stash
$ git pull
$ git stash pop

Misc Commands
$ git status
$ git diff origin/master
$ git log -v
$ git branch

- Yegappan

Guyzmo

unread,
May 29, 2016, 4:00:08 PM5/29/16
to vim...@googlegroups.com, Vimdev
Hi,

I could'nt resist, so please forgive the shameless self-promotion ☺

I have recently coded a little tool I called git-repo, that you can find
on pypi (pip install git-repo), that simplifies the process:

On Sat, May 28, 2016 at 12:19:21PM -0700, Yegappan Lakshmanan wrote:
> Fork the Vim repository

1. Fork, Clone and configure upstream branch:
% git hub fork --clone vim/vim

→ remote upstream is vim/vim and remote github is <you>/vim

I prefer using github instead of "origin" because that avoids confusion
between upstream and origin… I mean which one is which ? At least, you
know that github remote is always *yours*.

> Synchronizing a fork with the upstream
> $ git checkout master
> $ git fetch upstream
> $ git rebase upstream/master
> $ git push github master

well, that's still explicit, so it's nice!

> Creating a branch
> 1. Clone the Vim repository:

<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?
b. the https://github.com/<your-name>/vim/vim.git URL is wrong, it
should be https://github.com/<your-name>/vim.git

But let's consider that you're on a new computer, or you've erased your
local copy:

% git clone <your-name>/vim

> 2. Create a branch for the feature/bug fix:
> $ git checkout -b <branch-name>
> 3. Push the new branch to remote master:
> $ git push github <branch-name>
>
> Committing changes to a branch
> 1. Commit the changes:
> $ git commit -m "Commit comment"
> 2. Push the changes to the branch:
> $ git push github <branch-name>
>
> Creating a pull request
> Go to github.com and create a pull request for the branch to submit
> the changes for merging into the main Vim repository

% git hub request create "title" -m "description"

(I just realized that I forgot to implement that feature, so I'll just
implement it, so thank you for that ☺ I'll add it for v1.6.1)

> Synchronizing a branch with the master
<strikes this>
> $ git checkout master
> $ git fetch upstream
> $ git rebase upstream/master
> $ git checkout <branch-name>
> $ git rebase master
> $ git push --force
</strikes this>

Well there's a bunch of useless commands here!

% git checkout <branch-name>
% git fetch --all
% # here you can review what has changed before rebasing!
% git rebase upstream/master
% git push --force

you could even simplify this with:

% git checkout <branch-name>
% git pull upstream master
% git push --force

Though I prefer to review the fetched commits before changing my local
copy of the branch.

> Cloning a branch
> $ cd <some-directory>
> $ git clone https://github.com/<your-name>/vim.git

Again, why would you create a new directory for cloning a branch? You
can easily switch branches with `git checkout`. And if you've got
uncommitted changes, you can either commit them, or `git stash` them!

% git stash
> $ git checkout <branch-name>
% git stash pop

> 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

that will download all changes from all branches of all remotes, and
then you will be able to rebase onto the latest upstream's changes
at a convenient time for you:

% git rebase upstream/master

Though you can go review the changes you've fetched from the upstream
before rebasing.

> Misc Commands
> $ git status
> $ git diff origin/master
> $ git log -v
> $ git branch

Don't forget to read the help for most commands:

→ git help stash
→ git help rebase (git rebase -i is both awesome and dangerous)
→ git help reflog (which will save your ass in case you messed up)

On all platforms, you can review graphically using:

→ gitk --all

And on each platform, I can only advise you to use:

→ tig
→ gitg or git-cola on Xorg
→ gitxr on OSX

And add vimagit as a vim plugin, to be able to choose each chunks that
will make a commit, as if you're like me you're always fixing a few bugs
while you're implementing a new feature, but you want to make separate
commits in separate branches for bugfixes and features!

Finally, about the "self-promotion", git-repo is still alpha, I'm
already using it everyday, and it definitely needs a lot of polishing.
So please, if you like it (or the idea): report bugs, feature requests,
submit patches…
It's all on https://github.com/guyzmo/git-repo (it's also on gitlab and
bitbucket, BTW).

Cheers,

--
Guyzmo

Yegappan Lakshmanan

unread,
May 29, 2016, 9:06:15 PM5/29/16
to vim_dev
Hi,

On Sun, May 29, 2016 at 12:59 PM, 'Guyzmo' via vim_dev
<vim...@googlegroups.com> wrote:
> Hi,
>
> I couldn’t resist, so please forgive the shameless self-promotion ☺
>
> I have recently coded a little tool I called git-repo, that you can find
> on pypi (pip install git-repo), that simplifies the process:
>
> On Sat, May 28, 2016 at 12:19:21PM -0700, Yegappan Lakshmanan wrote:
>> Fork the Vim repository
>
> 1. Fork, Clone and configure upstream branch:
> % git hub fork --clone vim/vim
>
> → remote upstream is vim/vim and remote github is <you>/vim
>
> I prefer using github instead of "origin" because that avoids confusion
> between upstream and origin… I mean which one is which ? At least, you
> know that github remote is always *yours*.
>
>> Synchronizing a fork with the upstream
>> $ git checkout master
>> $ git fetch upstream
>> $ git rebase upstream/master
>> $ git push github master
>
> well, that's still explicit, so it's nice!
>
>> Creating a branch
>> 1. Clone the Vim repository:
>
> <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.

>
> b. the https://github.com/<your-name>/vim/vim.git URL is wrong, it
> should be https://github.com/<your-name>/vim.git
>

Yes. I will fix it.
I will try these steps and will update the list.

>
> you could even simplify this with:
>
> % git checkout <branch-name>
> % git pull upstream master
> % git push --force
>
> Though I prefer to review the fetched commits before changing my local
> copy of the branch.
>
>> Cloning a branch
>> $ cd <some-directory>
>> $ git clone https://github.com/<your-name>/vim.git
>
> Again, why would you create a new directory for cloning a branch? You
> can easily switch branches with `git checkout`. And if you've got
> uncommitted changes, you can either commit them, or `git stash` them!
>

As I mentioned above, I prefer to use a separate directory for each
feature development.

>
> % git stash
>> $ git checkout <branch-name>
> % git stash pop
>
>> 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?

- Yegappan

Guyzmo

unread,
May 30, 2016, 9:48:00 AM5/30/16
to vim...@googlegroups.com
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

Christian Brabandt

unread,
May 30, 2016, 2:03:23 PM5/30/16
to Vimdev, Bram Moolenaar
Hi Yegappan!
Thanks for that. I think we could put this at:
http://www.vim.org/git.php

CC'ing Bram.

Best,
Christian
--
Wie man sein Kind nicht nennen sollte:
Lee Besknochen

Guyzmo

unread,
May 30, 2016, 4:19:18 PM5/30/16
to Vimdev
Hi Christian,

I'm sorry I missed that page while lurking over the discussion on moving
to github. And really, it's nowhere near a reasonable git flow! Please,
consider updating the guide to the following:

--------------8<--------------8<--------------8<--------------8<--------------
You can obtain Vim for the first time with:

git clone https://github.com/vim/vim.git

And, if you don't have local changes, update to the latest version with:

cd vim
git pull

If you made some changes, e.g. to a makefile, you can keep them and
merge with the latest version with:

cd vim
git fetch origin
git rebase origin/master

Or you can keep it as a local commit:

git checkout -b local_changes
git commit -am "my local changes"

Then when you want to update:

cd vim
git fetch --all
git checkout local_changes
git rebase origin/master

When you want to start working on a new patch, create a new branch based
on master:

git fetch --all
git checkout -b <feature_branch> origin/master
# do your changes and all your commits

Once you have created a new fork of vim on github, you add your fork as
a new remote, and then you push to it as a new branch:

git remote add github g...@github.com:<your-name>/vim.git
git push -u github github/<feature_branch>

Then on github you can click on "create a pull request", based on that
branch. Of course, <feature_branch> is being the name of your feature.

You might want to read documentation on the following git commands (use
git help <command>):

git status
git diff origin/master
git log -v
git branch -av
git reflog

You might also want to have a look at different tools to visualize git
branches:

ncurses:
tig: http://jonas.nitro.dk/tig/

Xorg:
gitg: https://github.com/GNOME/gitg
git-cola: https://github.com/git-cola/git-cola

OSX:
gitx: https://rowanj.github.io/gitx/
gitup: https://github.com/git-up/GitUp


If you don't know how to use git, you'll probably want to look at the
Documentation.
-------------->8-------------->8-------------->8-------------->8--------------

Basically, I'd advise to avoid as much as possible to use `git pull` in
a git flow ­ except when just updating an unmodified local workspace to
the remote, as git pull is a shorthand for:

git fetch origin ; git rebase origin/master

But when you've got merges, then a git pull might not do things the way
you want, and using git stash is the wrong way around that.

Cheers,

--
Guyzmo

James McCoy

unread,
May 30, 2016, 6:19:26 PM5/30/16
to Vimdev
On Mon, May 30, 2016 at 10:18:59PM +0200, 'Guyzmo' via vim_dev wrote:
> Basically, I'd advise to avoid as much as possible to use `git pull` in
> a git flow ­ except when just updating an unmodified local workspace to
> the remote, as git pull is a shorthand for:
>
> git fetch origin ; git rebase origin/master

Since this is the second time you've repeated this, I figure it's worth
correcting. pull is more like “git fetch origin; git merge
origin/master”.

If you want to do a rebase, then it would be “git pull --rebase”.

Cheers,
--
James
GPG Key: 4096R/331BA3DB 2011-12-05 James McCoy <jame...@jamessan.com>
Reply all
Reply to author
Forward
0 new messages