Attempt to allow rebasing against another branch when updating

This code remains somewhat buggy, but sometimes works to allow
pulling and rebasing over a second branch.  Typical use case is when
there are Beancount entries yet to be merged into the official books
that one seeks to examine in testing.

The option `--rebaseBranch` is added for this purpose.

I am fairly confident this does not impact operation when you don't
use the `--rebaseBranch` option.
This commit is contained in:
Bradley M. Kuhn 2025-12-09 12:12:16 -08:00
parent a5967d4cf9
commit 0be51d997a
No known key found for this signature in database
GPG key ID: F15E8BD6D05E26B3

View file

@ -28,10 +28,12 @@ $ENV{PAGER} = "/usr/bin/cat";
my $BEANCOUNT_QUERY_CMD = "/usr/bin/bean-query"; my $BEANCOUNT_QUERY_CMD = "/usr/bin/bean-query";
my($VERBOSE, $BEANCOUNT_DIR, $LOAD_FILE, $BRANCH_NAME, $FIFO_DIR, $CLEAR_FILES, $GLUE) = (0, undef, undef, undef, undef, 1, 'BeAn'); my($VERBOSE, $BEANCOUNT_DIR, $LOAD_FILE, $BRANCH_NAME, $REBASE_BRANCH, $FIFO_DIR, $CLEAR_FILES, $GLUE) = (0, undef, undef, undef, undef, undef, 1, 'BeAn');
GetOptions("verbose=i" => \$VERBOSE, "beancountDir=s" => \$BEANCOUNT_DIR, 'glue=s' => \$GLUE, 'clearFiles!', \$CLEAR_FILES, GetOptions("verbose=i" => \$VERBOSE, "beancountDir=s" => \$BEANCOUNT_DIR, 'glue=s' => \$GLUE, 'clearFiles!', \$CLEAR_FILES,
"loadFile=s" => \$LOAD_FILE, "branchName=s" => \$BRANCH_NAME, 'fifoDir=s' => \$FIFO_DIR); "loadFile=s" => \$LOAD_FILE, "branchName=s" => \$BRANCH_NAME,
'rebaseBranch=s' => \$REBASE_BRANCH,
'fifoDir=s' => \$FIFO_DIR);
sub UsageAndExit($) { sub UsageAndExit($) {
print STDERR "usage: $0 --loadFile=/path/to/file.beancount --beancountDir=/path/to/beancountdir --fifoDir=/path/to/directory/for/fifos [ --glue=FOUR_CHAR_STRING --branchName=BRANCH_NAME --verbose=N ]\n"; print STDERR "usage: $0 --loadFile=/path/to/file.beancount --beancountDir=/path/to/beancountdir --fifoDir=/path/to/directory/for/fifos [ --glue=FOUR_CHAR_STRING --branchName=BRANCH_NAME --verbose=N ]\n";
@ -54,15 +56,18 @@ UsageAndExit("glue must be at exactly four characters")
my($tempRepository, $tempRepositoryDirectory); my($tempRepository, $tempRepositoryDirectory);
sub CleanupEvertything { sub CleanupEvertything {
$tempRepository = undef if (defined $tempRepository); # $tempRepository = undef if (defined $tempRepository);
$tempRepositoryDirectory = undef if (defined $tempRepositoryDirectory); # $tempRepositoryDirectory = undef if (defined $tempRepositoryDirectory);
StopRunningBeanQuery(); StopRunningBeanQuery();
croak @_; croak @_;
} }
UsageAndExit("--rebaseBranch can only be used in conjunction with --branchName")
if (defined $REBASE_BRANCH) and (not defined $BRANCH_NAME);
if (defined $BRANCH_NAME) { if (defined $BRANCH_NAME) {
my $absGitRepositoryDirectory = File::Spec->rel2abs( $BEANCOUNT_DIR ); my $absGitRepositoryDirectory = File::Spec->rel2abs( $BEANCOUNT_DIR );
$tempRepositoryDirectory = tempdir('beancountquerygoofydaemongit_' . $$ . '_XXXXXXXXXXX', $tempRepositoryDirectory = tempdir('beancountquerygoofydaemongit_' . $$ . '_XXXXXXXXXXX',
TMPDIR => 1, CLEANUP => 1); TMPDIR => 1); #, CLEANUP => 1);
print STDERR "Copy Git repository to $tempRepositoryDirectory...." if $VERBOSE > 2; print STDERR "Copy Git repository to $tempRepositoryDirectory...." if $VERBOSE > 2;
system($RSYNC_CMD, '-Ha', "$absGitRepositoryDirectory/", "$tempRepositoryDirectory/"); system($RSYNC_CMD, '-Ha', "$absGitRepositoryDirectory/", "$tempRepositoryDirectory/");
print STDERR "copy completed.\n" if $VERBOSE > 2; print STDERR "copy completed.\n" if $VERBOSE > 2;
@ -72,40 +77,54 @@ if (defined $BRANCH_NAME) {
$tempRepository->run(clean => '-fx', { quiet => 1 }); $tempRepository->run(clean => '-fx', { quiet => 1 });
$tempRepository->run(reset => '--hard', { quiet => 1 }); $tempRepository->run(reset => '--hard', { quiet => 1 });
$tempRepository->run(clean => '-fx', { quiet => 1 }); $tempRepository->run(clean => '-fx', { quiet => 1 });
$tempRepository->run(checkout => '$BRANCH_NAME', { quiet => 1 }); $tempRepository->run(checkout => $BRANCH_NAME, { quiet => 1 });
if (defined $REBASE_BRANCH) {
$tempRepository->run(rebase => $REBASE_BRANCH, { quiet => 1 });
}
} }
######################################################################
sub CheckUpstreamAndPull { sub CheckUpstreamAndPull {
# Returns true iff. a pull was required and the files have changed. # Returns true iff. a pull was required and the files have changed.
return 0 unless (defined $tempRepository); return 0 unless (defined $tempRepository);
my($retVal, $pullOutput) = (0, "");
my $options = { quiet => 1 }; my $options = { quiet => 1 };
if ($VERBOSE > 5) { if ($VERBOSE > 5) {
print STDERR "...clean & git pull..."; print STDERR "...clean & git pull...";
$options = {}; $options = {};
} }
print STDERR "...check if upstream Git changed..." if $VERBOSE > 5; print STDERR "...for check if upstream Git changed..." if $VERBOSE > 5;
my $updateOutput = $tempRepository->run(remote => 'update', $options); foreach my $branch ($REBASE_BRANCH, $BRANCH_NAME) {
print "$updateOutput" if defined $updateOutput and $updateOutput !~ /^\s*$/ and $VERBOSE > 5; next unless defined $branch;
my $curRev = $tempRepository->run('rev-parse' => '@'); print STDERR "...checking $branch now..." if $VERBOSE > 5;
my $remoteRev = $tempRepository->run('rev-parse' => '@{u}'); $tempRepository->run(checkout => $branch, $options);
my $baseRev = $tempRepository->run('merge-base' => '@', '@{u}'); my $updateOutput = $tempRepository->run(remote => 'update', $options);
print STDERR "...$curRev is current, $remoteRev is remote Rev $baseRev is base...\n" if $VERBOSE > 6; print "$updateOutput" if defined $updateOutput and $updateOutput !~ /^\s*$/ and $VERBOSE > 5;
if ($curRev eq $remoteRev) { my $curRev = $tempRepository->run('rev-parse' => '@');
print STDERR "no change..." if $VERBOSE > 5; my $remoteRev = $tempRepository->run('rev-parse' => '@{u}');
return 0; my $baseRev = $tempRepository->run('merge-base' => '@', '@{u}');
} elsif ($curRev eq $baseRev) { print STDERR "...on $branch, $curRev is current, $remoteRev is remote Rev $baseRev is base...\n" if $VERBOSE > 6;
$tempRepository->run(clean => '-fx', $options); if ($curRev eq $remoteRev) {
$tempRepository->run(reset => '--hard', $options); print STDERR "$branch: no change..." if $VERBOSE > 5;
$tempRepository->run(clean => '-fx', $options); next;
my $pullOutput = $tempRepository->run('pull'); } elsif ($curRev eq $baseRev) {
print STDERR "\nPerformed pull since remote updated:\n $pullOutput\n" if ($VERBOSE > 0); $tempRepository->run(clean => '-fx', $options);
return 1; $tempRepository->run(reset => '--hard', $options);
} else { $tempRepository->run(clean => '-fx', $options);
CleanupEvertything(); my $pullOutput = "";
die("our local Git has $curRev, upstream is at $remoteRev, and the base is $baseRev " . $pullOutput .= $tempRepository->run('pull');
"so give up entirely on trying to make this work."); $retVal = 1;
} else {
CleanupEvertything("our local Git has $curRev, upstream is at $remoteRev, and the base is $baseRev " .
"so give up entirely on trying to make this work.");
}
} }
if (defined $REBASE_BRANCH) {
$tempRepository->run(checkout => $BRANCH_NAME, $options);
$tempRepository->run(rebase => $REBASE_BRANCH, $options) if $retVal > 0;
}
return $retVal;
} }
######################################################################
my %options = ( my %options = (
create => 'yes', create => 'yes',
exclusive => 0, exclusive => 0,
@ -149,7 +168,7 @@ sub StartRunningBeanQuery {
push(@cmd, $LOAD_FILE); push(@cmd, $LOAD_FILE);
print STDERR "Starting beancount..." if $VERBOSE > 4; print STDERR "Starting beancount..." if $VERBOSE > 4;
$runningBeanQuery = Expect->spawn(@cmd); $runningBeanQuery = Expect->spawn(@cmd);
print STDERR "...spawned & loading data..." if $VERBOSE > 4; print STDERR "...spawned & loading data..." if $VERBOSE > 4;
$runningBeanQuery->log_stdout(0); $runningBeanQuery->log_stdout(0);
$runningBeanQuery->expect(undef, -re => '^\s*beancount\s*\>\s*') $runningBeanQuery->expect(undef, -re => '^\s*beancount\s*\>\s*')
or die("Unable to find beancount prompt, output was instead: ". or die("Unable to find beancount prompt, output was instead: ".