mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-22 19:08:09 +01:00
nmbug: Add 'clone' and replace FETCH_HEAD with @{upstream}
With two branches getting fetched (master and config), the branch referenced by FETCH_HEAD is ambiguous. For example, I have: $ cat FETCH_HEAD 41d7bfa7184cc93c9dac139d1674e9530799e3b0 \ not-for-merge branch 'config' of http://nmbug.tethera.net/git/nmbug-tags acd379ccb973c45713eee9db177efc530f921954 \ not-for-merge branch 'master' of http://nmbug.tethera.net/git/nmbug-tags (where I wrapped the line by hand). This means that FETCH_HEAD references the config branch: $ git rev-parse FETCH_HEAD 41d7bfa7184cc93c9dac139d1674e9530799e3b0 which breaks all of the FETCH_HEAD logic in nmbug (where FETCH_HEAD is assumed to point to the master branch). Instead of relying on FETCH_HEAD, use @{upstream} as the remote-tracking branch that should be merged/diffed/integrated into HEAD. @{upstream} was added in Git v1.7.0 (2010-02-12) [1], so relying on it should be fairly safe. One tricky bit is that bare repositories don't set upstream tracking branches by default: $ git clone --bare http://nmbug.tethera.net/git/nmbug-tags.git nmbug-bare $ cd nmbug-bare $ git remote show origin * remote origin Fetch URL: http://nmbug.tethera.net/git/nmbug-tags.git Push URL: http://nmbug.tethera.net/git/nmbug-tags.git HEAD branch: master Local refs configured for 'git push': config pushes to config (up to date) master pushes to master (up to date) While in a non-bare clone: $ git clone http://nmbug.tethera.net/git/nmbug-tags.git $ cd nmbug-tags $ git remote show origin * remote origin Fetch URL: http://nmbug.tethera.net/git/nmbug-tags.git Push URL: http://nmbug.tethera.net/git/nmbug-tags.git HEAD branch: master Remote branches: config tracked master tracked Local branch configured for 'git pull': master merges with remote master Local ref configured for 'git push': master pushes to master (up to date) From the clone docs [2]: --bare:: Make a 'bare' Git repository… Also the branch heads at the remote are copied directly to corresponding local branch heads, without mapping them to `refs/remotes/origin/`. When this option is used, neither remote-tracking branches nor the related configuration variables are created. To use @{upstream}, we need to the local vs. remote-tracking distinction, so this commit adds 'nmbug clone', replacing the previously suggested --bare clone with a non-bare --no-checkout --separate-git-dir clone into a temporary work directory. After which: $ git rev-parse @{upstream} acd379ccb973c45713eee9db177efc530f921954 gives us the master-branch commit. Existing nmbug users will have to run the configuration tweaks and re-fetch by hand. If you don't have any local commits, you could also blow away your NMBGIT repository and re-clone from scratch: $ nmbug clone http://nmbug.tethera.net/git/nmbug-tags.git Besides removing the ambiguity of FETCH_HEAD, this commit allows users to configure which upstream branch they want nmbug to track via 'git config', in case they want to change their upstream repository. [1]: http://git.kernel.org/cgit/git/git.git/tree/Documentation/RelNotes/1.7.0.txt [2]: http://git.kernel.org/cgit/git/git.git/tree/Documentation/git-clone.txt
This commit is contained in:
parent
5608e39a6b
commit
c200167426
1 changed files with 32 additions and 13 deletions
|
@ -26,6 +26,7 @@ my $ESCAPED_RX = qr{$ESCAPE_CHAR([A-Fa-f0-9]{2})};
|
||||||
my %command = (
|
my %command = (
|
||||||
archive => \&do_archive,
|
archive => \&do_archive,
|
||||||
checkout => \&do_checkout,
|
checkout => \&do_checkout,
|
||||||
|
clone => \&do_clone,
|
||||||
commit => \&do_commit,
|
commit => \&do_commit,
|
||||||
fetch => \&do_fetch,
|
fetch => \&do_fetch,
|
||||||
help => \&do_help,
|
help => \&do_help,
|
||||||
|
@ -125,6 +126,15 @@ sub do_archive {
|
||||||
system ('git', "--git-dir=$NMBGIT", 'archive', 'HEAD');
|
system ('git', "--git-dir=$NMBGIT", 'archive', 'HEAD');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub do_clone {
|
||||||
|
my $repository = shift;
|
||||||
|
|
||||||
|
my $tempwork = tempdir ('/tmp/nmbug-clone.XXXXXX', CLEANUP => 1);
|
||||||
|
system ('git', 'clone', '--no-checkout', '--separate-git-dir', $NMBGIT,
|
||||||
|
$repository, $tempwork) == 0
|
||||||
|
or die "'git clone' exited with nonzero value\n";
|
||||||
|
git ('config', '--unset', 'core.worktree');
|
||||||
|
}
|
||||||
|
|
||||||
sub is_committed {
|
sub is_committed {
|
||||||
my $status = shift;
|
my $status = shift;
|
||||||
|
@ -332,21 +342,24 @@ To discard your changes, run 'nmbug checkout'
|
||||||
|
|
||||||
sub do_pull {
|
sub do_pull {
|
||||||
my $remote = shift || 'origin';
|
my $remote = shift || 'origin';
|
||||||
|
my $branch = shift || 'master';
|
||||||
|
|
||||||
git ( 'fetch', $remote);
|
git ( 'fetch', $remote);
|
||||||
|
|
||||||
do_merge ();
|
do_merge ("$remote/$branch");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub do_merge {
|
sub do_merge {
|
||||||
|
my $commit = shift || '@{upstream}';
|
||||||
|
|
||||||
insist_committed ();
|
insist_committed ();
|
||||||
|
|
||||||
my $tempwork = tempdir ('/tmp/nmbug-merge.XXXXXX', CLEANUP => 1);
|
my $tempwork = tempdir ('/tmp/nmbug-merge.XXXXXX', CLEANUP => 1);
|
||||||
|
|
||||||
git ( { GIT_WORK_TREE => $tempwork }, 'checkout', '-f', 'HEAD');
|
git ( { GIT_WORK_TREE => $tempwork }, 'checkout', '-f', 'HEAD');
|
||||||
|
|
||||||
git ( { GIT_WORK_TREE => $tempwork }, 'merge', 'FETCH_HEAD');
|
git ( { GIT_WORK_TREE => $tempwork }, 'merge', $commit);
|
||||||
|
|
||||||
do_checkout ();
|
do_checkout ();
|
||||||
}
|
}
|
||||||
|
@ -407,11 +420,10 @@ sub do_status {
|
||||||
|
|
||||||
|
|
||||||
sub is_unmerged {
|
sub is_unmerged {
|
||||||
|
my $commit = shift || '@{upstream}';
|
||||||
|
|
||||||
return 0 if (! -f $NMBGIT.'/FETCH_HEAD');
|
my $fetch_head = git ('rev-parse', $commit);
|
||||||
|
my $base = git ( 'merge-base', 'HEAD', $commit);
|
||||||
my $fetch_head = git ('rev-parse', 'FETCH_HEAD');
|
|
||||||
my $base = git ( 'merge-base', 'HEAD', 'FETCH_HEAD');
|
|
||||||
|
|
||||||
return ($base ne $fetch_head);
|
return ($base ne $fetch_head);
|
||||||
|
|
||||||
|
@ -473,7 +485,7 @@ sub diff_index {
|
||||||
sub diff_refs {
|
sub diff_refs {
|
||||||
my $filter = shift;
|
my $filter = shift;
|
||||||
my $ref1 = shift || 'HEAD';
|
my $ref1 = shift || 'HEAD';
|
||||||
my $ref2 = shift || 'FETCH_HEAD';
|
my $ref2 = shift || '@{upstream}';
|
||||||
|
|
||||||
my $fh= git_pipe ( 'diff', "--diff-filter=$filter", '--name-only',
|
my $fh= git_pipe ( 'diff', "--diff-filter=$filter", '--name-only',
|
||||||
$ref1, $ref2);
|
$ref1, $ref2);
|
||||||
|
@ -561,10 +573,11 @@ git. Any extra arguments are used (one per line) as a commit message.
|
||||||
|
|
||||||
push local nmbug git state to remote repo
|
push local nmbug git state to remote repo
|
||||||
|
|
||||||
=item B<pull> [remote]
|
=item B<pull> [remote] [branch]
|
||||||
|
|
||||||
pull (merge) remote repo changes to notmuch. B<pull> is equivalent to
|
pull (merge) remote repo changes to notmuch. B<pull> is equivalent to
|
||||||
B<fetch> followed by B<merge>.
|
B<fetch> followed by B<merge>. The default remote is C<origin>, and
|
||||||
|
the default branch is C<master>.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
@ -572,6 +585,12 @@ B<fetch> followed by B<merge>.
|
||||||
|
|
||||||
=over 8
|
=over 8
|
||||||
|
|
||||||
|
=item B<clone> repository
|
||||||
|
|
||||||
|
Create a local nmbug repository from a remote source. This wraps
|
||||||
|
C<git clone>, adding some options to avoid creating a working tree
|
||||||
|
while preserving remote-tracking branches and upstreams.
|
||||||
|
|
||||||
=item B<checkout>
|
=item B<checkout>
|
||||||
|
|
||||||
Update the notmuch database from git. This is mainly useful to discard
|
Update the notmuch database from git. This is mainly useful to discard
|
||||||
|
@ -589,12 +608,12 @@ print help [for subcommand]
|
||||||
=item B<log> [parameters]
|
=item B<log> [parameters]
|
||||||
|
|
||||||
A simple wrapper for git log. After running C<nmbug fetch>, you can
|
A simple wrapper for git log. After running C<nmbug fetch>, you can
|
||||||
inspect the changes with C<nmbug log HEAD..FETCH_HEAD>
|
inspect the changes with C<nmbug log HEAD..@{upstream}>
|
||||||
|
|
||||||
=item B<merge>
|
=item B<merge> [commit]
|
||||||
|
|
||||||
Merge changes from FETCH_HEAD into HEAD, and load the result into
|
Merge changes from C<commit> into HEAD, and load the result into
|
||||||
notmuch.
|
notmuch. The default commit is C<@{upstream}>.
|
||||||
|
|
||||||
=item B<status>
|
=item B<status>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue