Commit Graph

68 Commits

Author SHA1 Message Date
Shawn O. Pearce
a949fa5d20 Automatically install Gerrit Code Review's commit-msg hook
Most users of repo are also using Gerrit Code Review, and will want
the commit-msg hook to be automatically installed into their local
projects so that Change-Ids are assigned when commits are created,
not when they are first uploaded.

Change-Id: Ide42e93b068832f099d68a79c2863d22145d05ad
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-08-22 18:22:04 -07:00
Shawn O. Pearce
a7ce096047 Allow meta projects to be created not under .repo/
Some types of manifests might prefer to put their meta project work
tree under topdir, rather than inside of the .repo/ directory.  We
can support that by allowing relpath to be optionally passed in.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-07-03 20:50:52 -07:00
Shawn O. Pearce
5f947bba69 init: add -o, --origin to name manifest remote
The -o option permits the user to control the name of the manifest's
remote, which normally is hardcoded to be 'origin', but can differ
because we derive it at runtime from the configuration file.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-07-03 20:50:52 -07:00
Shawn O. Pearce
cc6c79643e Make refs/remotes/m management the manifest object's responsibility
I plan to have the new submodule manifest format use a different
layout for the m refs than the XML manifest format has used in
the past.  Thus we need to move the behavior management into the
manifest object, and out of the project, so we can change it.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-07-03 20:03:38 -07:00
Shawn O. Pearce
ca3d8ff4fc Teach Project how to relink a .git/ in the work tree
The _LinkWorkTree method can now be used to relink the work tree,
such as if the real repository was moved to a different location
on disk.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-07-03 11:00:16 -07:00
Shawn O. Pearce
da88ff4411 Silence 'Current branch %s is up to date' during sync
We accidentally introduced this message during 1.6.8 by always
invoking `git rebase` when there were no new commits from the
upstream, but the user had local commits.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-03 11:09:31 -07:00
Shawn O. Pearce
fe200eeb52 Fix unnecessary self in project.py
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-01 15:28:21 -07:00
Shawn O. Pearce
3c8dea1f8d Change project.revision to revisionExpr and revisionId
The revisionExpr field now holds an expression from the manifest,
such as "refs/heads/master", while revisionId holds the current
commit-ish SHA-1 of the revisionExpr.  Currently that is only
filled in if the manifest points directly to a SHA-1.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-05-29 18:45:20 -07:00
Shawn O. Pearce
8ad8a0e61d Change DWIMery hack for dealing with rewound remote branch
The trick of looking at the reflog for the remote tracking branch
and only going back one commit works some of the time, but not all of
the time.  Its sort of relying on the fact that the user didn't use
`repo sync -n` or `git fetch` to only update the tracking branches
and skip the working directory update.

Doing this right requires looking through the history of the SHA-1
source (what the upstream used to be) and finding a spot where the
DAG diveraged away suddenly, and consider that to be the rewind
point.  That's really difficult to do, as we don't have a clear
picture of what that old point was.

A close approximation is to list all of the commits that are in
HEAD, but not the new upstream, and rebase all of those where the
committer email address is this user's email address.  In most cases,
this will effectively rebase only the user's new original work.

If the user is the project maintainer and rewound the branch
themselves, and they don't want all of the commits they have created
to be rebased onto the new upstream, they should handle the rebase
on their own, after the sync is complete.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-05-29 18:45:17 -07:00
Shawn O. Pearce
d1f70d9929 Refactor how projects parse remotes so it can be replaced
We now feed Project a RemoteSpec, instead of the Remote directly
from the XmlManifest.  This way the RemoteSpec already has the
full project URL, rather than just the base, permitting other
types of manifests to produce the URL in their own style.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-05-29 09:31:28 -07:00
Shawn O. Pearce
242b52690d Remove support for the extra <remote> definitions in manifests
These aren't that widely used, and actually make it difficult for
users to fully mirror a forest of repositories, and then permit
someone else to clone off that forest, rather then the original
upstream servers.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-05-19 13:01:52 -07:00
Ficus Kirkpatrick
bc7ef67d9b Automatically guess Gerrit change number in "repo upload --replace"
This feature only works if you have one commit to replace right now
(the common case).
2009-05-05 15:01:18 -07:00
Shawn O. Pearce
9360966bd2 Perform copy file activity when creating a new work directory
Performance improvements in repo sync caused us to skip out of the
initial Sync_LocalHalf without ever running CopyFiles, so we didn't
create the top level Makefile in new clients whose manifest request
one with a <copyfile> element.

Now we run CopyFiles after the initial read-tree that populates
the project working directory.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-21 10:54:59 -07:00
Shawn O. Pearce
05f66b6836 Fix 'repo sync' rebase logic on a published branch
If the current branch is published, but all published commits are
merged into the manifest revision, but there is also at least one
unpublished commit on the current branch, we should rebase the
unpublished commit, rather than creating a merge commit.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-21 08:28:06 -07:00
Shawn O. Pearce
fb2316146f Automatically use SSH control master support during sync
By creating a background ssh "control master" process which lives
for the duration of our sync cycle we can easily cut the time for
a no-op sync of 132 projects from 60s to 18s.

Bug: REPO-11
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 16:50:47 -07:00
Shawn O. Pearce
3d2cdd0ea5 Highlight projects which still have sync failures during 'repo status'
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 15:26:10 -07:00
Shawn O. Pearce
552ac89929 Modify 'repo abandon' to be more like 'repo checkout' and 'repo start'
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 15:15:24 -07:00
Shawn O. Pearce
89e717d948 Improve checkout performance for the common unmodified case
Most projects will have their branch heads matching in all branches,
so switching between them should be just a matter of updating the
work tree's HEAD symref.  This can be done in pure Python, saving
quite a bit of time over forking 'git checkout'.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 15:04:41 -07:00
Shawn O. Pearce
0f0dfa3930 Add progress meter to 'repo start'
This is mostly useful if the number of projects to switch is many
(e.g. all of Android) and a large number of them are behind the
current manifest revision.  We wind up needing to run git just to
make the working tree match, and that often makes the command take
a couple of seconds longer than we'd like.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 14:53:39 -07:00
Shawn O. Pearce
76ca9f8145 Make usage of open safer by setting binary mode and closing fds
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 14:48:03 -07:00
Shawn O. Pearce
accc56d82b Speed up 'repo start' by removing some forks
Its quite common for most projects to be matching the current
manifest revision, as most developers only modify one or two projects
at any one time.  We can speed up `repo start foo` (that impacts
the entire client) by performing most of the branch creation and
switch operations in pure Python, and thus avoid 4 forks per project.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 14:45:51 -07:00
Shawn O. Pearce
9bb9617858 Remove unused methods from project.ReviewableBranch
These used to be used back when we had Gerrit 1.x support and used
HTTP based uploads to transmit changes for review.  Since we moved
entirely to Gerrit 2.x, these are no longer called.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 10:53:27 -07:00
Shawn O. Pearce
f690687671 Only fetch repo once-per-day under normal 'repo sync' usage
Its unlikely that a new version of repo will be delivered in any
given day, so we now check only once every 24 hours to see if repo
has been updated.  This reduces the sync cost, as we no longer need
to contact the repo distribution servers every time we do a sync.

repo selfupdate can still be used to force a check.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 10:49:00 -07:00
Shawn O. Pearce
336f7bd0ed Avoid git fork on the common case of repo not changing
Usually repo is upgraded only once a week, if that often.  Most of
the time we invoke HasChanges on the repo project (or even on the
manifest project) the current HEAD will resolve to the same SHA-1
as the remote tracking ref, and there are therefore no changes.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-18 10:39:28 -07:00
Shawn O. Pearce
0f3dd233ec Avoid unnecessary git symbolic-ref calls during repo sync
If the m/BRANCH ref is already pointing at the value set in the
manifest there is no reason to set it again.  Leave it alone,
thus saving a full fork+exec call.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-17 21:03:45 -07:00
Shawn O. Pearce
fbcde472ca Improve repo sync performance by avoid git forks
By resolving the current HEAD and the manifest revision using pure
Python, we can in the common case of "no changes" avoid a lot of
git operations and directly jump out of the local sync method.

This reduces the no-op `repo sync -l` time for Android's 114 projects
from more than 6s to under 0.8s.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-17 21:03:45 -07:00
Shawn O. Pearce
d237b69865 Implement git ref reading purely in Python
Its much faster to read the refs from 114 projects when the reader
is pure Python and just doing file IO than forking 114 git commands
and parsing their output.

The reader caches refs based upon file mtimes.  If any single ref
file has been modified since the last read, we re-read the entire
repository's ref namespace.  This simplifies the code as we don't
need to worry about shooting down symbolic-refs, but it may cause
more IO than is necessary if only one ref gets updated.

This change drops `repo branches` in Android from 1.658s to 0.206s.
Likewise, `repo sync` improves dramatically as well.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-17 21:03:41 -07:00
Shawn O. Pearce
5b23f24881 Implement 'git symbolic-ref HEAD' in Python
This is invoked once per project in `repo sync`.  Taking it out
saves about 1/114 of a second, so on a large set of projects like
Android it can save up to a full second of sync time.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-17 20:59:44 -07:00
Shawn O. Pearce
006734b798 Remove confusing message from repo sync output
Someone pointed out this message isn't always the truth; so we
shouldn't print it.  The code path is executed when there are
published commits, yet our output talks about unpublished ones.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-17 10:28:25 -07:00
Shawn O. Pearce
350cde4c4b Change repo sync to be more friendly when updating the tree
We now try to sync all projects that can be done safely first, before
we start rebasing user commits over the upstream.  This has the nice
effect of making the local tree as close to the upstream as possible
before the user has to start resolving merge conflicts, as that extra
information in other projects may aid in the conflict resolution.

Informational output is buffered and delayed until calculation for
all projects has been done, so that the user gets one concise list
of notice messages, rather than it interrupting the progress meter.

Fast-forward output is now prefixed with the project header, so the
user can see which project that update is taking place in, and make
some relation of the diffstat back to the project name.

Rebase output is now prefixed with the project header, so that if
the rebase fails, the user can see which project we were operating
on and can try to address the failure themselves.

Since rebase sits on a detached HEAD, we now look for an in-progress
rebase during sync, so we can alert the user that the given project
is in a state we cannot handle.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-16 11:21:18 -07:00
Shawn O. Pearce
48244781c2 Refactor error message display in project.py
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-16 08:25:57 -07:00
Shawn O. Pearce
19a83d8085 Use default rebase during sync instead of rebase -i
rebase interactive (aka rebase -i) has changed in newer versions
of git, and doesn't always generate the sequence of commits the
same way it used to.  It also doesn't handle having a previously
applied commit try to be applied again.

The default rebase algorithm is better suited to our needs.
It uses --ignore-if-in-upstream when generating the patch series
for git-am, and git-am with its 3-way fallback is able to handle
a rename case just as well as the cherry-pick variant used by -m.
Its also a generally faster implementation.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-16 08:23:29 -07:00
Shawn O. Pearce
161f445a4d status: tell the user the working tree is clean
If there is nothing output at all, tell the user the working tree is
completely clean.  It just gives them a bit more of a warm-fuzzy
feeling knowing repo and until the end.  It also more closely
matches with the output of git status.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-10 19:01:08 -07:00
Shawn O. Pearce
3e768c9dc7 Add 'repo sync -d' to detach projects from their current topic
The -d flag moves the project back to a detached HEAD state,
matching what is listed in the manifest.  This can be useful to
set a client to something stable (or at least well-known), such as
before a sequence of 'repo download' commands are used to get some
changes for testing.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-10 17:08:02 -07:00
Shawn O. Pearce
0a389e94de Make 'repo start' restartable upon failures
If `repo start foo` fails due to uncommitted and unmergeable changes
in a single project, we have switched half of the projects over to
the new target branches, but didn't on the one that failed to move.

This change improves the situation by doing three things differently:

- We keep going when we encounter an error, so other projects
  that can successfully switch still switch.

- We ignore projects whose current branch is already on the
  requested name; they are logically already setup.

- We checkout the branch if it already exists, rather than
  trying to recreate the branch.

Bug: REPO-22
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-10 16:21:18 -07:00
Shawn O. Pearce
2675c3f8b5 Don't capture stdout during 'repo checkout'
There isn't any great value in buffering stdout into memory
coming from git checkout.  So don't bother doing it.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-10 16:20:25 -07:00
Shawn O. Pearce
27b07327bc Add a repo branches subcommand to describe current branches
We now display a summary of the available topic branches in this
client, based upon a sorted union of all existing projects.

Bug: REPO-21
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-04-10 16:02:48 -07:00
Wink Saville
02d7945eb8 Add checkout command.
Teach repo how to checkout a branch in all projects or a list
of specific projects.

Bug: REPO-21
2009-04-10 13:01:24 -07:00
Shawn O. Pearce
c7a4eefa7e Add repo manifest -o to save a manifest
This can be useful to create a new manifest from an existing client,
especially if the client wants to use the "-r" option to set each
project's revision to the current commit SHA-1, making a sort of a
tag file that can be used to recreate this exact state elsewhere.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-03-05 10:32:38 -08:00
Shawn O. Pearce
2816d4f387 Set core.bare to true on mirror repositories
When creating a mirror repository we will always be using a bare
repository.  Setting $GIT_DIR/config to have core.bare = true is
reasonable and helps Git to recognize the environment it is in.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-03-03 17:53:18 -08:00
Shawn O. Pearce
6a5644d392 Get rid of the horrible android import work around hack
Months ago when the Android Open Source Project launched we had some
import errors that had to be fixed and worked over.  These hacks
were here to help users update their clients to newer versions of
the imported code.

Its very likely all clients have either been deleted, or have been
updated and have the fixed imports.  So we don't need this hack in
repo anymore.

If a very ancient client still existed, it would need to be created
from scratch anyway, due to the Android cupcake branch merging
into master and the manifest changes not being able to be handled
correctly by repo.  A new client wouldn't have the incorrectly
imported code in it, and thus wouldn't need this hack.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-03-03 13:52:20 -08:00
Shawn O. Pearce
fe08675956 Fix repo status when there are renamed/copied files
I missed a parameter in the format string, but still provided the
value in the parameter list, so the format failed to produce an
output message.

Bug: REPO-15
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-03-03 13:49:48 -08:00
Shawn O. Pearce
559b846b17 Report better errors when a project revision is invalid
If a manifest specifies an invalid revision property, give the
user a better error message detaling the problem, instead of an
ugly Python traceback with a strange Git error message.

Bug: REPO-2
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-03-02 12:56:08 -08:00
Shawn O. Pearce
7c6c64d463 Fix repo prune output to sort by branch name
We didn't always sort the output.  Now we do.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-03-02 12:38:45 -08:00
Shawn O. Pearce
3778f9d47e Fix repo prune to work on git 1.6.1-rc3~5 and later
Prior to git 1.6.1-rc3~5 the output of 'git branch -d' matched:

  Deleted branch (.*)\.

where the subgroup grabbed the branch name. In v1.6.1-rc3~5 (aka
a126ed0a01e265d7f3b2972a34e85636e12e6d34) Brandon Casey changed
the output to include the SHA-1 of the branch name, now matching
the pattern:

  Deleted branch (.*) \([0-9a-f]*\)\.

Instead of parsing the output of git branch we now re-obtain the
list of branches after the deletion attempt and perform a set
difference in memory to determine which branches we were able to
successfully delete.

Bug: REPO-9
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-03-02 12:38:36 -08:00
Shawn O. Pearce
370e3fa666 Remove the protobuf based HTTP upload code path
Now that Gerrit2 has been released and the only supported upload
protocol is direct git push over SSH we no longer need the large
and complex protobuf client library, or the upload chunking logic
in gerrit_upload.py.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-01-26 10:55:39 -08:00
Shawn O. Pearce
b54a392c9a Support Gerrit2's ssh:// based upload
In Gerrit2 uploads are sent over "git push ssh://...", as this
is a more efficient transport and is easier to code from external
scripts and/or direct command line usage by an end-user.

Gerrit1's HTTP POST based format is assumed if the review server
does not have the /ssh_info URL available on it.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-01-05 16:34:27 -08:00
Marcelo E. Magallon
21f7385400 Remove astray comma
There's an extra "," at the end of the line, which is causing
trouble when the manifest file specifies a revision for a
project.  Since the default manifest file doesn't specify
revisions for the projects, the problem has gone unnoticed.

Thanks to Barry Silverman <barry@disus.com> for spotting the
issue and providing a patch.

Signed-off-by: Marcelo E. Magallon <marcelo.magallon@gmail.com>
2008-12-31 04:45:04 +00:00
Joe Onorato
2896a79120 Add --review and --cc flags to repo upload, so you can
assign reviewers when you upload changes.
2008-11-19 11:55:06 -05:00
Shawn O. Pearce
c99883fee9 Teach 'repo upload --replace' how to add replacement patch sets
Users are prompted with the list of known changes we are about
to upload, and they can fill out the current change numbers for
any changes which already exist in the data store.  For each of
those changes the change number and commit id is sent as part of
the upload request, so Gerrit can insert the new commit as a new
patch set of the existing change, rather than make a new change.

This facility permits developers to replace a patch so they can
address comments made on a prior version of the same change.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2008-11-12 09:12:19 -08:00