Documente Academic
Documente Profesional
Documente Cultură
1 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
This post is aimed at those who have been using Eclipse for a while, and probably have been using either the
baked-in CVS or external SVN providers to store their source code. The content of the post is about Git: what it
means to you, as an Eclipse user, and specifically, how it affects how you obtain or work with projects from
Eclipse.org.
This post is not about the relative merits of Git over CVS/SVN, or of Git versus other distributed version control
systems (DVCS) like Mercurial (Hg). Other sites can give those flavours if needed.
Once you understand the conceptual differences between CVS/SVN and Git, and then subsequently start to use Git,
you may find it very difficult to go back. You should really start to experiment only if you think you're going to migrate
in the near future, because using Git is like watching TV in colour: once you've discovered it, it's really difficult to go
back to black & white.
Once you start to use a DVCS, it's very unlikely you'll want to go back
Contents
1 Centralised version control systems
2 Distributed Version Control Systems
3 How does it work?
4 Changesets and branches
5 Merging
6 Pulling and pushing
7 Cloning and remotes
8 Initialising, committing and branching
9 Worked example
10 Rebasing and fast-forwarding
19-06-2016 22:38
2 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
disconnected from SVN, like diff from the last-known checkout. However, in general, you are prevented from doing
many of the operations that are possible while connected.)
The first problem is rarely apparent for those working with Eclipse in a location at (or near) the repository itself.
Those in the same continent will rarely experience delays due to global network variation; in addition, they tend to be
employed in an organisation and sit at a desktop connected to wired networking for most of the day. Road warriors
(those with laptops and who code from the local coffee shop) tend to operate in a more frequently disconnected
mode, which limits repository functionality to when they are connected.
The second problem is simply an artifact of the way in which patches work. These are generally performed against
HEAD (a snapshot in time) and then applied later (sometimes months or even eight years later
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=4922)). Although they record the version of the file they were
patched against, the patch itself is sensitive to big changes in the file, sometimes leading to the patch being
inapplicable. Even relatively simple operations, like a file rename, can throw a well-formed CVCS patch out of the
window.
19-06-2016 22:38
3 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
than an n-n set of links, the graph usually self-organises into a tree-like structure, logically associating with one
point that acts as a funnel for everything else. In a sense, that's a master repository everyone has already
made the choice; now you have to understand it. Should an oracle intervene, a neo-master can be chosen.
There is no master repository
3. Given that there is no master repository, it becomes clear that the repository must live in its entirety on each of
the nodes in the DVCS. This usually leads to fears about the size of the repository, even taking into account
that storage is cheap. A key point here is that DVCS repositories are usually far smaller than their counterpart
CVCS repositories, not least of the reasons for which being that everyone has to have a full repository in order
to do any work. It's a natural consequence that they're smaller. However, they're smaller also because each
repository contains far less scope than a CVCS repository. For example, most organisations will have one
mammoth CVCS repository with several thousand top-level 'modules' (or 'projects') underneath. Because of
the administrative overhead of 'creating a new repository', it is often easier to reuse the same one for
everything. (SVN put some limits on how wide it could grow, which CVS tended not to have; but even so, the
main Apache SVN (http://svn.apache.org/viewvc?view=revision&revision=908283) is over 900k
revisions.) By contrast, a DVCS is usually nothing more than a directory with a few administrative files inside.
It doesn't require administrator privileges or specific ports; in fact, since there's no central server to speak of, it
doesn't even need to be shared by network protocols. As a result, a DVCS repository is much more granular
and easy to create than a conventional CVCS repository. Firstly, it's always on your machine (there's no
centralised server to configure) and secondly, all you need access to is a file system. So typically, a DVCS
repository will often be at the level of an Eclipse project or project working set. For example, although the
CVS RT repository (http://dev.eclipse.org/viewcvs/index.cgi/?root=RT_Project) is shared by Equinox
(http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.equinox/?root=RT_Project) and ECF
(http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ecf/?root=RT_Project&view=log), a DVCS-based
solution would almost certainly see the Equinox and ECF projects in their own repositories; perhaps, even
breaking down further into (say) ECF-Doc and ECF-Bundles. Think of a DVCS repository as one or a few
Eclipse projects instead of hundreds of projects together.
DVCS repositories are much smaller, typically because they contain only a small number of highlyrelated projects
4. That's not a question. Look, if you want the benefits of a centralised DVCS with pessimistic locking and
pessimistic users, then go look at ClearCase (http://www-01.ibm.com/software/awdtools/clearcase/).
Friends don't let friends use ClearCase
19-06-2016 22:38
4 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
--- a/README.txt
+++ b/README.txt
@@ -1 +1 @@
-SVN is great
+Git is great
we can create a 'hash' using (for example) md5 , to generate the string 0878a8189e6a3ae1ded86d9e9c7cbe3f . When
referring to our change with others, we can use this hash to identify the change in question.
Changesets are identified by a hash of their contents
Clearly, though, this doesn't work on its own. What happens if we do the same change later on? It would have the
same change, and we don't want the same hash value.
What happens is that a changeset contains two things; the change itself, and a back-pointer to the previous
changeset. In other words, we end up with something like:
previous: 48b2179994d494485b79504e8b5a6b23ce24a026
--- a/README.txt
+++ b/README.txt
@@ -1 +1 @@
-SVN is great
+Git is great
Each time, the value of the changeset includes a pointer to what comes before, so the hash is continually changing.
Note: Rather than using md5 , as shown here, most DVCS (including Git) use an sha1 hash instead. Also, the exact
way that the prior elements in the tree are stored, and their relationships, isn't accurately portrayed above; however,
it gives sufficiently well the idea of how they are organised.
19-06-2016 22:38
5 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
Merging
With great power comes great flexibility, but ultimately, you want to get your changes into some kind of merged
stream (like HEAD). One of the fears of unconstrained branching is that of unconstrained merge pains later on. SVN
makes this slightly less difficult than CVS, but unless you merge to HEAD frequently, you can easily get lost
particularly when refactorings start happening.
It's painful to merge in a CVCS; therefore branches tend not to happen
Fortunately, DVCSs are all about merging. Given that each node in the changeset tree contains a pointer to its
previous node (and transitively, to the beginning of time), it's much more powerful than the standard flat CVCS diff. In
other words, not only do you know what changes need to be made, but also at what point in history they need to be
made. So, if you have a changeset that renames a file, and then merge in a changeset that points to the file as it was
before it was renamed, a CVCS will just fall over; but a DVCS will be able to apply the change before the rename
occurred, and then play forward the changes.
Merges are just the weaving together of two (or more) local branches into one. The git merge
(http://www.kernel.org/pub/software/scm/git/docs/git-merge.html) documentation has some graphical examples
of this; but basically, it's just like any other merge you've seen. However, unlike CVCS, you don't have to specify
anything about where you're merging from and to; the trees automatically know what their split point was in the past,
and can work it out from there.
19-06-2016 22:38
6 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
We can then keep up-to-date with what's happening on the remote server by executing a pull from the remote:
git pull origin
...but we're not limited to one repository. Let's say we wanted to create a separate copy on GitHub
(http://www.github.com) for easy forking; we can do that by adding another remote Git URL and then pushing to
that:
git remote add github http://github.com/alblue/babel.git (http://github.com/alblue/babel.git)
git push github
We can now use git push and git pull to move items between the two git repositories. By default, they both
refer to the special-named origin, but you can specify whatever remote to talk to on the command line.
19-06-2016 22:38
7 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
Origin is the name of the default remote, but you can have many remotes per repository.
Worked example
Here's a transcript of working with setting up an initial repository, then copying data to and from a 'remote' repository,
albeit in a different directory on the same system. The instructions are for a Unix-like environment (e.g. Cygwin on
Windows).
19-06-2016 22:38
8 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
$ mkdir /tmp/example
$ cd /tmp/example
$ git init
Initialized empty Git repository in /tmp/example/.git/
$ echo "Hello, world" > README.txt
$ git commit # Won't commit files by default
# On branch master
#
# Initial commit
#
# Untracked files:
#
(use "git add <file>..." to include in what will be committed)
#
#
README.txt
nothing added to commit but untracked files present (use "git add" to track)
$ git add README.txt # Similar to Team -> Add to Version Control
$ # git commit # Would prompt for message
$ git commit -m "Added README.txt"
[master (root-commit) 0dd1f35] Added README.txt
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 README.txt
$ echo "Hello, solar system" > README.txt
$ git commit
# On branch master
# Changed but not updated:
#
(use "git add <file>..." to update what will be committed)
#
(use "git checkout -- <file>..." to discard changes in working directory)
#
#
modified:
README.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m "Updated README.txt"
[master 9b1939a] Updated README.txt
1 files changed, 1 insertions(+), 1 deletions(-)
$ git log --graph --oneline # Shows graph nodes (not much here) and change info
* 9b1939a Updated README.txt
* 0dd1f35 Added README.txt
$ git checkout -b french 0dd1f35 # create and switch to a new branch 'french'
Switched to a new branch 'french'
$ cat README.txt
Hello, world
$ echo "Bonjour, tout le monde" > README.txt
$ git add README.txt # or commit -a
$ git commit -m "Ajout README.txt"
[french 66a644c] Ajout README.txt
1 files changed, 1 insertions(+), 1 deletions(-)
$ git log --graph --oneline
* 66a644c Ajout README.txt
* 0dd1f35 Added README.txt
$ git checkout -b web 0dd1f35 # Create and checkout a branch 'web' from initial commit
$ echo '<a href="http://git.eclipse.org (http://git.eclipse.org)">git.eclipse.org</a>' > index.html
$ git add index.html
$ git commit -m "Added homepage"
19-06-2016 22:38
9 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
19-06-2016 22:38
10 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
19-06-2016 22:38
11 of 11
http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
*
f0fde4e Merge change I11dc6200
|\
| * 86dfb92 Mark the next version as 0.6
* |
0c8c04d Merge change I908e4c77
|\ \
| |/
|/|
| * 843dc8f Add support for logAllRefUpdates configuration parameter
* | 74ba6fc Remove TODO file and move to bugzilla
* | ba7c6e8 Fix SUBMITTING_PATCHES to follow the Eclipse IP process
* | c5e8589 Fix tabs-to-spaces in SUBMITTING_PATCHES
* | 677ca7b Update SUBMITTING_PATCHES to point to Contributor Guide
* | 8847865 Document protected members of RevObjectList
* | a0a0ce8 Make it possible to clear a PlotCommitList
* | 4a3870f Include description for missing bundle prereqs
|/
* 144b16d Cleanup MANIFEST.MF in JGit
What happened here was that two branches split off from change 144b16d , ultimately driving another branch at
74ba6fc and a few merges (at 0c8c04d and f0fde4e ). (You can see a similar effect in Google Code's Hg view of
Wave Protocol (http://code.google.com/p/wave-protocol/source/list).) Ultimately, whilst the DVCS can handle
these long-running branches and subsequent merges, humans tend to prefer to see fewer branches in the final
repository.
A fast-forward merge (in Git terms) is one which doesn't need any kind of merge operation. This usually happens
when you are moving from an older branch to a newer branch on the same timeline; such as when updating to a
newer version from a remote repository. These are essentially just moving the HEAD pointer further down the
branch.
A rebase is uprooting the branch from the original commit, and re-writing history as if it had been done from the
current point in time. For example, in the above Git trace, 1441b16d to 843dc8f to 0c8c0fd was only one commit
off the main tree. Had the change been rebased on 74ba6fc , then we would have only seen a single timeline across
those commits. It's generally considered good practice to rebase changes prior to pushing to a remote tree to avoid
these kind of fan-outs, but it's not necessary to do so. Furthermore, the rebase operation changes the sha1 hashes
of your tree, which can affect those who have forked your repository. Best practice is to frequently rebase your
changes in your own local repository, but once they've been made public (by pushing to a shared repository) to avoid
rebasing further.
Rebasing replants your tree; but do it on local branches only
This page was last modified 17:27, 31 July 2015 by Ron Craig (/index.php?title=User:Roncraig007.yahoo.com&action=edit&redlink=1). Based
on work by Matthias Sohn (/User:Matthias.sohn.sap.com), Daniel U. Thibault (/User:Daniel.thibault.drdc-rddc.gc.ca) and Tjeerd Verhagen
(/index.php?title=User:Tjeerd.verhagen.gmail.com&action=edit&redlink=1) and others (/index.php?title=EGit/Git_For_Eclipse_Users&
action=credits).
19-06-2016 22:38