cvs-migration documentation update
Here's some changes to the cvs-migration.txt. As usual, in my attempt to make things clearer someone may have found I've made them less so, or I may have just gotten something wrong; so any review is welcomed. I can break up this sort of thing into smaller steps if preferred, the monolothic patch is just a bit simpler for me for this sort of thing. I moved the material describing shared repository management from core-tutorial.txt to cvs-migration.txt, where it seems more appropriate, and combined two sections to eliminate some redundancy. I also revised the earlier sections of cvs-migration.txt, mainly trying to make it more concise. I've left the last section of cvs-migration.txt (on CVS annotate alternatives) alone for now. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
		
				
					committed by
					
						
						Junio C Hamano
					
				
			
			
				
	
			
			
			
						parent
						
							1506fc34f7
						
					
				
				
					commit
					b8bc67cef3
				
			@ -1623,123 +1623,7 @@ suggested in the previous section may be new to you. You do not
 | 
				
			|||||||
have to worry. git supports "shared public repository" style of
 | 
					have to worry. git supports "shared public repository" style of
 | 
				
			||||||
cooperation you are probably more familiar with as well.
 | 
					cooperation you are probably more familiar with as well.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For this, set up a public repository on a machine that is
 | 
					See link:cvs-migration.txt[git for CVS users] for the details.
 | 
				
			||||||
reachable via SSH by people with "commit privileges".  Put the
 | 
					 | 
				
			||||||
committers in the same user group and make the repository
 | 
					 | 
				
			||||||
writable by that group.  Make sure their umasks are set up to
 | 
					 | 
				
			||||||
allow group members to write into directories other members
 | 
					 | 
				
			||||||
have created.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You, as an individual committer, then:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- First clone the shared repository to a local repository:
 | 
					 | 
				
			||||||
------------------------------------------------
 | 
					 | 
				
			||||||
$ git clone repo.shared.xz:/pub/scm/project.git/ my-project
 | 
					 | 
				
			||||||
$ cd my-project
 | 
					 | 
				
			||||||
$ hack away
 | 
					 | 
				
			||||||
------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Merge the work others might have done while you were hacking
 | 
					 | 
				
			||||||
  away:
 | 
					 | 
				
			||||||
------------------------------------------------
 | 
					 | 
				
			||||||
$ git pull origin
 | 
					 | 
				
			||||||
$ test the merge result
 | 
					 | 
				
			||||||
------------------------------------------------
 | 
					 | 
				
			||||||
[NOTE]
 | 
					 | 
				
			||||||
================================
 | 
					 | 
				
			||||||
The first `git clone` would have placed the following in
 | 
					 | 
				
			||||||
`my-project/.git/remotes/origin` file, and that's why this and
 | 
					 | 
				
			||||||
the next step work.
 | 
					 | 
				
			||||||
------------
 | 
					 | 
				
			||||||
URL: repo.shared.xz:/pub/scm/project.git/ my-project
 | 
					 | 
				
			||||||
Pull: master:origin
 | 
					 | 
				
			||||||
------------
 | 
					 | 
				
			||||||
================================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- push your work as the new head of the shared
 | 
					 | 
				
			||||||
  repository.
 | 
					 | 
				
			||||||
------------------------------------------------
 | 
					 | 
				
			||||||
$ git push origin master
 | 
					 | 
				
			||||||
------------------------------------------------
 | 
					 | 
				
			||||||
If somebody else pushed into the same shared repository while
 | 
					 | 
				
			||||||
you were working locally, `git push` in the last step would
 | 
					 | 
				
			||||||
complain, telling you that the remote `master` head does not
 | 
					 | 
				
			||||||
fast forward.  You need to pull and merge those other changes
 | 
					 | 
				
			||||||
back before you push your work when it happens.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The `git push` command without any explicit refspec parameter
 | 
					 | 
				
			||||||
pushes the refs that exist both in the local repository and the
 | 
					 | 
				
			||||||
remote repository.  So the last `push` can be done with either
 | 
					 | 
				
			||||||
one of these:
 | 
					 | 
				
			||||||
------------
 | 
					 | 
				
			||||||
$ git push origin
 | 
					 | 
				
			||||||
$ git push repo.shared.xz:/pub/scm/project.git/
 | 
					 | 
				
			||||||
------------
 | 
					 | 
				
			||||||
as long as the shared repository does not have any branches
 | 
					 | 
				
			||||||
other than `master`.
 | 
					 | 
				
			||||||
[NOTE]
 | 
					 | 
				
			||||||
============
 | 
					 | 
				
			||||||
If you created your shared repository by cloning from somewhere
 | 
					 | 
				
			||||||
else, you may have the `origin` branch.  Your developers
 | 
					 | 
				
			||||||
typically do not use that branch; remove it.  Otherwise, that
 | 
					 | 
				
			||||||
would be pushed back by the `git push origin` because your
 | 
					 | 
				
			||||||
developers' repository would surely have `origin` branch to keep
 | 
					 | 
				
			||||||
track of the shared repository, and would be counted as "exist
 | 
					 | 
				
			||||||
on both ends".
 | 
					 | 
				
			||||||
============
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Advanced Shared Repository Management
 | 
					 | 
				
			||||||
-------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Being able to push into a shared repository means being able to
 | 
					 | 
				
			||||||
write into it.  If your developers are coming over the network,
 | 
					 | 
				
			||||||
this means you, as the repository administrator, need to give
 | 
					 | 
				
			||||||
each of them an SSH access to the shared repository machine.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In some cases, though, you may not want to give a normal shell
 | 
					 | 
				
			||||||
account to them, but want to restrict them to be able to only
 | 
					 | 
				
			||||||
do `git push` into the repository and nothing else.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can achieve this by setting the login shell of your
 | 
					 | 
				
			||||||
developers on the shared repository host to `git-shell` program.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[NOTE]
 | 
					 | 
				
			||||||
Most likely you would also need to list `git-shell` program in
 | 
					 | 
				
			||||||
`/etc/shells` file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This restricts the set of commands that can be run from incoming
 | 
					 | 
				
			||||||
SSH connection for these users to only `receive-pack` and
 | 
					 | 
				
			||||||
`upload-pack`, so the only thing they can do are `git fetch` and
 | 
					 | 
				
			||||||
`git push`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You still need to create UNIX user accounts for each developer,
 | 
					 | 
				
			||||||
and put them in the same group.  Make sure that the repository
 | 
					 | 
				
			||||||
shared among these developers is writable by that group.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
. Initializing the shared repository with `git-init-db --shared`
 | 
					 | 
				
			||||||
helps somewhat.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
. Run the following in the shared repository:
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
------------
 | 
					 | 
				
			||||||
$ chgrp -R $group repo.git
 | 
					 | 
				
			||||||
$ find repo.git -type d -print | xargs chmod ug+rwx,g+s
 | 
					 | 
				
			||||||
$ GIT_DIR=repo.git git repo-config core.sharedrepository true
 | 
					 | 
				
			||||||
------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The above measures make sure that directories lazily created in
 | 
					 | 
				
			||||||
`$GIT_DIR` are writable by group members.  You, as the
 | 
					 | 
				
			||||||
repository administrator, are still responsible to make sure
 | 
					 | 
				
			||||||
your developers belong to that shared repository group and set
 | 
					 | 
				
			||||||
their umask to a value no stricter than 027 (i.e. at least allow
 | 
					 | 
				
			||||||
reading and searching by group members).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can implement finer grained branch policies using update
 | 
					 | 
				
			||||||
hooks.  There is a document ("control access to branches") in
 | 
					 | 
				
			||||||
Documentation/howto by Carl Baldwin and JC outlining how to (1)
 | 
					 | 
				
			||||||
limit access to branch per user, (2) forbid overwriting existing
 | 
					 | 
				
			||||||
tags.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Bundling your work together
 | 
					Bundling your work together
 | 
				
			||||||
---------------------------
 | 
					---------------------------
 | 
				
			||||||
 | 
				
			|||||||
@ -1,126 +1,182 @@
 | 
				
			|||||||
git for CVS users
 | 
					git for CVS users
 | 
				
			||||||
=================
 | 
					=================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Ok, so you're a CVS user. That's ok, it's a treatable condition, and the
 | 
					So you're a CVS user. That's ok, it's a treatable condition.  The job of
 | 
				
			||||||
first step to recovery is admitting you have a problem. The fact that
 | 
					this document is to put you on the road to recovery, by helping you
 | 
				
			||||||
you are reading this file means that you may be well on that path
 | 
					convert an existing cvs repository to git, and by showing you how to use a
 | 
				
			||||||
already.
 | 
					git repository in a cvs-like fashion.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The thing about CVS is that it absolutely sucks as a source control
 | 
					Some basic familiarity with git is required.  This
 | 
				
			||||||
manager, and you'll thus be happy with almost anything else. git,
 | 
					link:tutorial.html[tutorial introduction to git] should be sufficient.
 | 
				
			||||||
however, may be a bit 'too' different (read: "good") for your taste, and
 | 
					 | 
				
			||||||
does a lot of things differently. 
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
One particular suckage of CVS is very hard to work around: CVS is
 | 
					First, note some ways that git differs from CVS:
 | 
				
			||||||
basically a tool for tracking 'file' history, while git is a tool for
 | 
					 | 
				
			||||||
tracking 'project' history.  This sometimes causes problems if you are
 | 
					 | 
				
			||||||
used to doing very strange things in CVS, in particular if you're doing
 | 
					 | 
				
			||||||
things like making branches of just a subset of the project.  git can't
 | 
					 | 
				
			||||||
track that, since git never tracks things on the level of an individual
 | 
					 | 
				
			||||||
file, only on the whole project level. 
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The good news is that most people don't do that, and in fact most sane
 | 
					  * Commits are atomic and project-wide, not per-file as in CVS.
 | 
				
			||||||
people think it's a bug in CVS that makes it tag (and check in changes)
 | 
					 | 
				
			||||||
one file at a time.  So most projects you'll ever see will use CVS
 | 
					 | 
				
			||||||
'as if' it was sane.  In which case you'll find it very easy indeed to
 | 
					 | 
				
			||||||
move over to git. 
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
First off: this is not a git tutorial. See
 | 
					  * Offline work is supported: you can make multiple commits locally,
 | 
				
			||||||
link:tutorial.html[Documentation/tutorial.txt] for how git
 | 
					    then submit them when you're ready.
 | 
				
			||||||
actually works. This is more of a random collection of gotcha's
 | 
					 | 
				
			||||||
and notes on converting from CVS to git.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Second: CVS has the notion of a "repository" as opposed to the thing
 | 
					  * Branching is fast and easy.
 | 
				
			||||||
that you're actually working in (your working directory, or your
 | 
					 | 
				
			||||||
"checked out tree").  git does not have that notion at all, and all git
 | 
					 | 
				
			||||||
working directories 'are' the repositories.  However, you can easily
 | 
					 | 
				
			||||||
emulate the CVS model by having one special "global repository", which
 | 
					 | 
				
			||||||
people can synchronize with.  See details later, but in the meantime
 | 
					 | 
				
			||||||
just keep in mind that with git, every checked out working tree will
 | 
					 | 
				
			||||||
have a full revision control history of its own.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Every working tree contains a repository with a full copy of the
 | 
				
			||||||
 | 
					    project history, and no repository is inherently more important than
 | 
				
			||||||
 | 
					    any other.  However, you can emulate the CVS model by designating a
 | 
				
			||||||
 | 
					    single shared repository which people can synchronize with; see below
 | 
				
			||||||
 | 
					    for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Importing a CVS archive
 | 
					Importing a CVS archive
 | 
				
			||||||
-----------------------
 | 
					-----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Ok, you have an old project, and you want to at least give git a chance
 | 
					First, install version 2.1 or higher of cvsps from
 | 
				
			||||||
to see how it performs. The first thing you want to do (after you've
 | 
					link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
 | 
				
			||||||
gone through the git tutorial, and generally familiarized yourself with
 | 
					sure it is in your path.  The magic command line is then
 | 
				
			||||||
how to commit stuff etc in git) is to create a git'ified version of your
 | 
					 | 
				
			||||||
CVS archive.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Happily, that's very easy indeed. git will do it for you, although git
 | 
					-------------------------------------------
 | 
				
			||||||
will need the help of a program called "cvsps":
 | 
					$ git cvsimport -v -d <cvsroot> -C <destination> <module>
 | 
				
			||||||
 | 
					-------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	http://www.cobite.com/cvsps/
 | 
					This puts a git archive of the named CVS module in the directory
 | 
				
			||||||
 | 
					<destination>, which will be created if necessary.  The -v option makes
 | 
				
			||||||
 | 
					the conversion script very chatty.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
which is not actually related to git at all, but which makes CVS usage
 | 
					The import checks out from CVS every revision of every file.  Reportedly
 | 
				
			||||||
look almost sane (ie you almost certainly want to have it even if you
 | 
					cvsimport can average some twenty revisions per second, so for a
 | 
				
			||||||
decide to stay with CVS). However, git will want 'at least' version 2.1
 | 
					medium-sized project this should not take more than a couple of minutes.
 | 
				
			||||||
of cvsps (available at the address above), and in fact will currently
 | 
					Larger projects or remote repositories may take longer.
 | 
				
			||||||
refuse to work with anything else.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Once you've gotten (and installed) cvsps, you may or may not want to get
 | 
					The main trunk is stored in the git branch named `origin`, and additional
 | 
				
			||||||
any more familiar with it, but make sure it is in your path. After that,
 | 
					CVS branches are stored in git branches with the same names.  The most
 | 
				
			||||||
the magic command line is
 | 
					recent version of the main trunk is also left checked out on the `master`
 | 
				
			||||||
 | 
					branch, so you can start adding your own changes right away.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	git cvsimport -v -d <cvsroot> -C <destination> <module>
 | 
					The import is incremental, so if you call it again next month it will
 | 
				
			||||||
 | 
					fetch any CVS updates that have been made in the meantime.  For this to
 | 
				
			||||||
 | 
					work, you must not modify the imported branches; instead, create new
 | 
				
			||||||
 | 
					branches for your own changes, and merge in the imported branches as
 | 
				
			||||||
 | 
					necessary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
which will do exactly what you'd think it does: it will create a git
 | 
					Development Models
 | 
				
			||||||
archive of the named CVS module. The new archive will be created in the
 | 
					------------------
 | 
				
			||||||
subdirectory named <destination>; it'll be created if it doesn't exist.
 | 
					 | 
				
			||||||
Default is the local directory.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
It can take some time to actually do the conversion for a large archive
 | 
					CVS users are accustomed to giving a group of developers commit access to
 | 
				
			||||||
since it involves checking out from CVS every revision of every file,
 | 
					a common repository.  In the next section we'll explain how to do this
 | 
				
			||||||
and the conversion script is reasonably chatty unless you omit the '-v'
 | 
					with git.  However, the distributed nature of git allows other development
 | 
				
			||||||
option, but on some not very scientific tests it averaged about twenty
 | 
					models, and you may want to first consider whether one of them might be a
 | 
				
			||||||
revisions per second, so a medium-sized project should not take more
 | 
					better fit for your project.
 | 
				
			||||||
than a couple of minutes.  For larger projects or remote repositories,
 | 
					 | 
				
			||||||
the process may take longer.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
After the (initial) import is done, the CVS archive's current head
 | 
					For example, you can choose a single person to maintain the project's
 | 
				
			||||||
revision will be checked out -- thus, you can start adding your own
 | 
					primary public repository.  Other developers then clone this repository
 | 
				
			||||||
changes right away.
 | 
					and each work in their own clone.  When they have a series of changes that
 | 
				
			||||||
 | 
					they're happy with, they ask the maintainer to pull from the branch
 | 
				
			||||||
 | 
					containing the changes.  The maintainer reviews their changes and pulls
 | 
				
			||||||
 | 
					them into the primary repository, which other developers pull from as
 | 
				
			||||||
 | 
					necessary to stay coordinated.  The Linux kernel and other projects use
 | 
				
			||||||
 | 
					variants of this model.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The import is incremental, i.e. if you call it again next month it'll
 | 
					With a small group, developers may just pull changes from each other's
 | 
				
			||||||
fetch any CVS updates that have been happening in the meantime. The
 | 
					repositories without the need for a central maintainer.
 | 
				
			||||||
cut-off is date-based, so don't change the branches that were imported
 | 
					 | 
				
			||||||
from CVS.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can merge those updates (or, in fact, a different CVS branch) into
 | 
					Emulating the CVS Development Model
 | 
				
			||||||
your main branch:
 | 
					-----------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	git resolve HEAD origin "merge with current CVS HEAD"
 | 
					Start with an ordinary git working directory containing the project, and
 | 
				
			||||||
 | 
					remove the checked-out files, keeping just the bare .git directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The HEAD revision from CVS is named "origin", not "HEAD", because git
 | 
					------------------------------------------------
 | 
				
			||||||
already uses "HEAD". (If you don't like 'origin', use cvsimport's
 | 
					$ mv project/.git /pub/repo.git
 | 
				
			||||||
'-o' option to change it.)
 | 
					$ rm -r project/
 | 
				
			||||||
 | 
					------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next, give every team member read/write access to this repository.  One
 | 
				
			||||||
 | 
					easy way to do this is to give all the team members ssh access to the
 | 
				
			||||||
 | 
					machine where the repository is hosted.  If you don't want to give them a
 | 
				
			||||||
 | 
					full shell on the machine, there is a restricted shell which only allows
 | 
				
			||||||
 | 
					users to do git pushes and pulls; see gitlink:git-shell[1].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Emulating CVS behaviour
 | 
					Put all the committers should in the same group, and make the repository
 | 
				
			||||||
-----------------------
 | 
					writable by that group:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------
 | 
				
			||||||
 | 
					$ chgrp -R $group repo.git
 | 
				
			||||||
 | 
					$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s
 | 
				
			||||||
 | 
					$ GIT_DIR=repo.git git repo-config core.sharedrepository true
 | 
				
			||||||
 | 
					------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
So, by now you are convinced you absolutely want to work with git, but
 | 
					Make sure committers have a umask of at most 027, so that the directories
 | 
				
			||||||
at the same time you absolutely have to have a central repository.
 | 
					they create are writable and searchable by other group members.
 | 
				
			||||||
Step back and think again. Okay, you still need a single central
 | 
					 | 
				
			||||||
repository? There are several ways to go about that:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Designate a person responsible to pull all branches. Make the
 | 
					Suppose this repository is now set up in /pub/repo.git on the host
 | 
				
			||||||
repository of this person public, and make every team member
 | 
					foo.com.  Then as an individual commiter you can clone the shared
 | 
				
			||||||
pull regularly from it.
 | 
					repository:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2. Set up a public repository with read/write access for every team
 | 
					------------------------------------------------
 | 
				
			||||||
member. Use "git pull/push" as you used "cvs update/commit".  Be
 | 
					$ git clone foo.com:/pub/repo.git/ my-project
 | 
				
			||||||
sure that your repository is up to date before pushing, just
 | 
					$ cd my-project
 | 
				
			||||||
like you used to do with "cvs commit"; your push will fail if
 | 
					------------------------------------------------
 | 
				
			||||||
what you are pushing is not up to date.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
3. Make the repository of every team member public. It is the
 | 
					and hack away.  The equivalent of `cvs update` is
 | 
				
			||||||
responsibility of each single member to pull from every other
 | 
					 | 
				
			||||||
team member.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------
 | 
				
			||||||
 | 
					$ git pull origin
 | 
				
			||||||
 | 
					------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					which merges in any work that others might have done since the clone
 | 
				
			||||||
 | 
					operation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[NOTE]
 | 
				
			||||||
 | 
					================================
 | 
				
			||||||
 | 
					The first `git clone` places the following in the
 | 
				
			||||||
 | 
					`my-project/.git/remotes/origin` file, and that's why the previous step
 | 
				
			||||||
 | 
					and the next step both work.
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					URL: foo.com:/pub/project.git/ my-project
 | 
				
			||||||
 | 
					Pull: master:origin
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can update the shared repository with your changes using:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------------------------------------------
 | 
				
			||||||
 | 
					$ git push origin master
 | 
				
			||||||
 | 
					------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If some else has updated the repository more recently, `git push`, like
 | 
				
			||||||
 | 
					`cvs commit`, will complain, in which case you must pull any changes
 | 
				
			||||||
 | 
					before attempting the push again.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the `git push` command above we specify the name of the remote branch
 | 
				
			||||||
 | 
					to update (`master`).  If we leave that out, `git push` tries to update
 | 
				
			||||||
 | 
					any branches in the remote repository that have the same name as a branch
 | 
				
			||||||
 | 
					in the local repository.  So the last `push` can be done with either of:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					$ git push origin
 | 
				
			||||||
 | 
					$ git push repo.shared.xz:/pub/scm/project.git/
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					as long as the shared repository does not have any branches
 | 
				
			||||||
 | 
					other than `master`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[NOTE]
 | 
				
			||||||
 | 
					============
 | 
				
			||||||
 | 
					Because of this behaviour, if the shared repository and the developer's
 | 
				
			||||||
 | 
					repository both have branches named `origin`, then a push like the above
 | 
				
			||||||
 | 
					attempts to update the `origin` branch in the shared repository from the
 | 
				
			||||||
 | 
					developer's `origin` branch.  The results may be unexpected, so it's
 | 
				
			||||||
 | 
					usually best to remove any branch named `origin` from the shared
 | 
				
			||||||
 | 
					repository.
 | 
				
			||||||
 | 
					============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Advanced Shared Repository Management
 | 
				
			||||||
 | 
					-------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Git allows you to specify scripts called "hooks" to be run at certain
 | 
				
			||||||
 | 
					points.  You can use these, for example, to send all commits to the shared
 | 
				
			||||||
 | 
					repository to a mailing list.  See link:hooks.txt[Hooks used by git].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can enforce finer grained permissions using update hooks.  See
 | 
				
			||||||
 | 
					link:howto/update-hook-example.txt[Controlling access to branches using
 | 
				
			||||||
 | 
					update hooks].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CVS annotate
 | 
					CVS annotate
 | 
				
			||||||
------------
 | 
					------------
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user