Revision control (also known as version control, source control or (source) code management (SCM)) is the management of multiple revisions of the same unit of information. It is most commonly used in engineering and software development to manage ongoing development of digital documents like application source code, art resources such as blueprints or electronic models and other critical information that may be worked on by a team of people. Changes to these documents are identified by incrementing an associated number or letter code, termed the "revision number", "revision level", or simply "revision" and associated historically with the person making the change.
I like how it is super, super fast. (esp. when one is used to Subversion and having to wait a while just to review the log/previous commits, or to commit)
I like how the overhead for forking someone else's project is very, very, very low (esp. when using GitHub), which makes me much more likely to start modifying other people's code. And I find it beneficial that I can commit my changes so they are saved and revision controlled even if no one else uses my contributions.
The man pages are usually helpful, and often contain helpful real-life examples.
It has so many commands available, unlike Subversion, and it's easy to add your own by just putting a git-__ command in the path. Also, I like how many of its commands are easily wrapable (machine-parseable).
It is very customizable -- lots of config options available.
Make it easier to tell which commands are plumbing and which are porcelain, so I don't waste my time doing 'man git-whatchanged' (git-whatchanged *sounds* like it's a useful user-level tool) only to find out when I get there that it's just a plumbing tool. It would be nice if I could just do tab completion on git- to see all the useful commands available without being distracted by plumbing tools (although on occasion I may have found them useful for porcelain-level stuff...). Maybe prefix them with git-plumbing- instead of just git-?.
|Categories/Tags:||[Distributed revision control software (category)]|
|Description:||Git is popular version control system designed to handle very large projects with speed and efficiency; it is used mainly for various open source projects, most notably the Linux kernel.
|Authors:||Linus Torvalds, Junio C Hamano
Git is distributed version control system focused on speed, effectivity and real-world usability on large projects. Its highlights include:
Besides providing a version control system, the Git project provides a generic low-level toolkit for tree history storage and directory content management. Traditionally, the toolkit is called the plumbing. Several other projects (so-called porcelains) offer compatible version control interfaces - see the related tools list.
- Strong support for non-linear development. Git supports rapid and convenient branching and merging, and includes powerful tools for visualizing and navigating a non-linear development history.
- Distributed development. Like most other modern version control systems, Git gives each developer a local copy of the entire development history, and changes are copied from one such repository to another. These changes are imported as additional development branches, and can be merged in the same way as a locally developed branch. Repositories can be easily accessed via the efficient Git protocol (optionally wrapped in ssh) or simply using HTTP - you can publish your repository anywhere without any special webserver configuration required.
- Efficient handling of large projects. Git is very fast and scales well even when working with large projects and long histories. It is commonly an order of magnitude faster than most other revision control systems, and several orders of magnitude faster on some operations. It also uses an extremely efficient packed format for long-term revision storage that currently tops any other open source version control system.
- Cryptographic authentication of history. The Git history is stored in such a way that the name of a particular revision (a "commit" in Git terms) depends upon the complete development history leading up to that commit. Once it is published, it is not possible to change the old versions without it being noticed. Also, tags can be cryptographically signed.
- Toolkit design. Following the Unix tradition, Git is a collection of many small tools written in C, and a number of scripts that provide convenient wrappers. It is easy to chain the components together to do other clever things.
Version Control Interface layers
- Cogito is a popular version control system on top of Git. It aims at seamless user interface and ease of use, providing generally smoother user experience than the "raw" Git interface and indeed also many other version control systems. However, it also lacks many advanced capabilities of Git and is currently being slowly phased out.
- Stacked Git provides a Quilt-like patch management functionality in the Git environment. You can easily manage your patches in the scope of Git until they get merged upstream.
- git-gui is a simple Tk based graphical interface for common Git operations. Git-gui is shipped with Git.
- gitk is a TCL/TK GUI for browsing history of Git repositories. Developed separeted but distributed with stock Git.
- qgit is a QT GUI for browsing history of Git repositories, similar to gitk but with more features.
- gitweb provides full-fledged web interface for Git repositories. gitweb is now part of the core Git distribution.
http://repo.or.cz/w/git-homepage.git is an example of accessing a Git repository from the Web
Things You Should Know
There is couple of important concepts it is good to know when starting with Git. If you are in hurry though, you can skip this section and only get back to it when you get seriously confused; it should be possible to pick up with just using your intuition.
- Repositories. With Subversion, for each project there is a single repository at some detached central place where all the history is and which you checkout and commit into. Git works differently, each copy of the project tree (we call that the working copy) carries its own repository around (in the .git subdirectory in the project tree root). So you can have local and remote branches. You can also have a so-called bare repository which is not attached to a working copy; that is useful especially when you want to publish your repository. We will get to that.
- URL. In Subversion the URL identifies the location of the repository and the path inside the repository, so you organize the layout of the repository and its meaning. Normally you would have trunk/, branches/ and tags/ directories. In Git the URL is just the location of the repository, and it always contains branches and tags. One of the branches is the default (normally named master).
- Revisions. Subversion identifies revisions with ids of decimal numbers growing monotonically which are typically small (although they can get quickly to hundreds of thousands for large projects). That is impractical in distributed systems like Git. Git identifies revisions with SHA1 ids, which are long 128-bit numbers written in hex. It may look scary at first, but in practice it is not a big hurdle - you can refer to the latest revision by HEAD, its parent as HEAD^ and its parent as HEAD^^ = HEAD~2 (you can go on adding carrets), cut'n'paste helps a lot and you can write only the few leading digits of a revision - as long as it is unique, Git will guess the rest. (You can do even more advanced stuff with revision specifiers, see the git-rev-parse manpage for details.)
- Commits. Each commit has an author and a committer field, which record who and when created the change and who committed it (Git is designed to work well with patches coming by mail - in that case, the author and the committer will be different). Git will try to guess your realname and email, but especially with email it is likely to get it wrong. You can check it using git config -l and set them with:git config --global user.name "Your Name Comes Here" git config --global user.email email@example.com
- Commands. The Git commands are in the form git command. You can interchangeably use the git-command form as well.
- Colours. Git can produce colourful output with some commands; since some people hate colors way more than the rest likes them, by default the colors are turned off. If you would like to have colors in your output:git config --global color.diff auto git config --global color.status auto git config --global color.branch auto
- Visualize. You may find it convenient to watch your repository using the gitk repository as you go.
Git embeds special information in the diffs about adds, removals and mode changes:git apply
That will apply the patch while telling Git about and performing those "meta-changes".
...git commit -a
And as a bonus, if you pass it the -v parameter it will show the whole patch being committed in the editor so that you can do a quick last-time review.
By the way, if you screwed up committing, there's not much you can do with Subversion, except using some enigmatic svnadmin subcommands. Git does better - you can amend your latest commit (re-edit the metadata as well as update the tree) using git commit --amend, or toss your latest commit away completely using git reset HEAD^, this will not change the working tree.
Now that we have committed some stuff, you might want to review your history:git log git blame file
The log command works quite similar in SVN and Git; again, git log is quite powerful, please look through its options to see some of the stuff it can do.
The blame command is more powerful as it can detect lines movement, even with file copies and renames [!]. But there are big chances that you probably want to do something different! Usually, when using annotate you are looking for the origin of some piece of code, and the so-called pickaxe of Git is much more comfortable tool for that job (
git log -Sstringshows the commits which add or remove any file data matching string).
You can see the contents of a file, the listing of a directory or a commit with:
git show rev:path/to/file git show rev:path/to/directory git show rev svn cat url svn list url svn log -rrev url svn diff -crev url
Tagging and branching
Subversion marks certain checkpoints in history through copies, the copy is usually placed in a directory named tags. Git tags are quite more powerful. The Git tag can have an arbitrary description attached (the first line is special as in the commit case), some people actually store the whole release announcements in the tag descriptions. The identity of the person who tagged is stored (again following the same rules as identity of the committer). You usually tag commits but if you want, you can tag files (or trees, but that's a bit lowlevel) as well. And the tag can be cryptographically PGP signed to verify the identity (by Git's nature of working, that signature also confirms the validity of the associated revision, its history and tree). So, let's do it: git tag -a name svn copy http://example.com/svn/trunk http://example.com/svn/tags/name
To list tags and to show the tag message:
git tag -l git show tag svn list http://example.com/svn/tags/ svn log --limit 1 http://example.com/svn/tags/tag
Like Subversion, Git can do branches (surprise surprise!). In Subversion, you basically copy your project to a subdirectory. In Git, you tell it, well, to create a branch.
git branch branch git checkout branch svn copy http://example.com/svn/trunk http://example.com/svn/branches/branch svn switch http://example.com/svn/branches/branch
The first command creates a branch, the second command switches your tree to a certain branch. You can pass an extra argument to git branch to base your new branch on a different revision than the latest one.
You can list your branches conveniently using the aforementioned git-branch command without arguments the listing of branches. The current one is denoted by an "*".git branch
To move your tree to some older revision, use:git checkout rev git checkout prevbranch
or you could create a temporary branch. In Git you can make commits on top of the older revision and use it as another branch.
Git supports merging between branches much better than Subversion - history of both branches is preserved over the merges and repeated merges of the same branches are supported out-of-the-box. Make sure you are on one of the to-be-merged branches and merge the other one now:
git merge branch
(assuming the branch was created in revision 20 and you are inside a working copy of trunk)svn merge -r 20:HEAD http://example.com/svn/branches/branch
If changes were made on only one of the branches since the last merge, they are simply replayed on your other branch (so-called fast-forward merge). If changes were made on both branches, they are merged intelligently (so-called three-way merge): if any changes conflicted, git merge will report them and let you resolve them, updating the rest of the tree already to the result state; you can git commit when you resolve the conflicts. If no changes conflicted, a commit is made automatically with a conveniently log message (or you can do git merge --no-commit branch to review the merge result and then do the commit yourself).
Aside of merging, sometimes you want to just pick one commit from a different branch. To apply the changes in revision rev and commit them to the current branch use:git cherry-pick revsvn merge -c rev url
So far, we have neglected that Git is a distributed version control system. It is time for us to set the record straight - let's grab some stuff from remote sites.
If you are working on someone else's project, you usually want to clone its repository instead of starting your own. We've already mentioned that at the top of this document:git clone url
Now you have the default branch (normally master), but in addition you got all the remote branches and tags. In clone's default setup, the default local branch tracks the origin remote, which represents the default branch in the remote repository.
Remote branch, you ask? Well, so far we have worked only with local branches. Remote branches are a mirror image of branches in remote repositories and you don't ever switch to them directly or write to them. Let me repeat - you never mess with remote branches. If you want to switch to a remote branch, you need to create a corresponding local branch which will "track" the remote branch:git checkout --track -b origin/branch branchsvn switch url
If you always want to track remote branches (and forget about the --track) you can set:git config --global branch.autosetupmerge auto
You can add more remote branches, to a cloned repository as well as just an initialized one, using git remote add remote url. The command git remote lists all the remotes repositories and git remote show remote shows the branches in a remote repository.
Now, how to get any new changes from a remote repository? You fetch them: git fetch. At this point they are in your repository and you can examine them using git log origin (git log HEAD..origin to see just the changes you don't have in your branch), diff them, and obviously, merge them - just do git merge origin. Note that if you don't specify a branch for fetch, it will conveniently default to the tracking remote.
Since you frequently just fetch + merge the tracking remote branch, there is a command to automate that:git pull
Sharing the Work
Your local repository can be used by others to pull changes, but normally you would have a private repository and a public repository. The public repository is where everybody pulls and you... do the opposite? Push your changes? Yes! We do git push remote which will push all the local branches with a corresponding remote branch - note that this works generally only over SSH (or HTTP but with special webserver setup). It is highly recommended to set up a SSH key and an SSH agent mechanism so that you don't have to type in a password all the time.
One important thing is that you should push only to remote branches that are not currently checked out on the other side (for the same reasons you never switch to a remote branch locally)! Otherwise the working copy at the remote branch will get out of date and confusion will ensue. The best way to avoid that is to push only to remote repositories with no working copy at all - so called bare repositories which are commonly used for public access or developers' meeting point - just for exchange of history where a checked out copy would be a waste of space anyway. You can create such a repository, see Setting up a public repository for details.
Git can work with the same workflow as Subversion, with a group of developers using a single repository for exchange of their work - the only change is that their changes aren't submitted automatically but they have to push (however, you can set up a post-commit hook that will push for you every time you commit; that loses the flexibility to fix a screwed up commit, though). The developers have to have either an entry in htaccess (for HTTP DAV) or a UNIX account (for SSH) - you can restrict their shell account only to Git pushing/fetching by using the git-shell login shell.
You can also exchange patches by mail. Git has very good support for patches incoming by mail. You can apply them by feeding mailboxes with patch mails to git am. If you want to send patches, use
possibly git send-email. To maintain a set of patches it is best to use the StGIT tool - see the StGIT Crash Course).
http://www.kernel.org/pub/software/scm/git/docs/tutorial.html A tutorial introduction to git (for version 1.5.1 or newer)
http://git.or.cz/gitwiki/GitSvnComparsion GitSvnComparsion - GitWiki
- It's incredibly fast.
- No other SCM that I have used has been able to keep up with it, and I've used a lot, including Subversion, Perforce, darcs, BitKeeper, ClearCase and CVS.
- It's fully distributed.
- The repository owner can't dictate how I work. I can create branches and commit changes while disconnected on my laptop, then later synchronize that with any number of other repositories.
- Unlike Subversion branches carry along their complete history.
- without having to perform a strange copy and walk through the copy. When using Subversion I always found it awkward to look at the history of a file on branch that occurred before the branch was created. [I assume he means: It shows history for the file that existed even before the branch was created.]
- Branch merging is simpler and more automatic in Git.
- In Subversion you need to remember what was the last revision you merged from so you can generate the correct merge command. Git does this automatically, and always does it right. Which means there's less chance of making a mistake when merging two branches together.
- Creating a repository is a trivial operation [don't need to specify a special location for the repository like you would with svnadmin create, because the repository is right there in the working copy!]:
- mkdir foo; cd foo; git init-db
- That's it. Which means I create a Git repository for everything these days.
- The repository's internal file formats are incredible simple.
- This means repair is very easy to do, but even better because its so simple its very hard to get corrupted. I don't think anyone has ever had a Git repository get corrupted. I've seen Subversion with fsfs corrupt itself. And I've seen Berkley DB corrupt itself too many times to trust my code to the bdb backend of Subversion.
- Git's file format is very good at compressing data, despite
- its very simple format. The Mozilla project's CVS repository is about 3 GB; its about 12 GB in Subversion's fsfs format. In Git its around 300 MB.
http://changelog.complete.org/posts/528-Whose-Distributed-VCS-Is-The-Most-Distributed.html Whose Distributed VCS Is The Most Distributed?
|Categories/Tags:||[Distributed revision control software (category)]
|Categories/Tags:||[Distributed revision control software (category)]
|Categories/Tags:||[Distributed revision control software (category)]|
|As listed in other directories:||Wikipedia
Darcs is a distributed revision control system by David Roundy that was designed to replace the centralized CVS. Two particular features in its design distinguish it from CVS. Each copy of the source tree acts as a full repository, allowing several different versions to be maintained in different locations. Patches are global to the repository and are subject under certain conditions to reordering, as governed by the project's "theory of patches".
Sample darcs repository: http://chneukirchen.org/repos/testspec/
Every user has access to the full command set, removing boundaries between server and client or committer and non-committers.
Darcs is easy to learn and efficient to use because it asks you questions in response to simple commands, giving you choices in your work flow. You can choose to record one change in a file, while ignoring another. As you update from upstream, you can review each patch name, even the full "diff" for interesting patches.
Originally developed by physicist David Roundy, darcs is based on a unique algebra of patches.
This smartness lets you respond to changing demands in ways that would otherwise not be possible. Learn more about spontaneous branches with darcs.