Skip to content

Commit 2880499

Browse files
cshinaverchf2117
cshinaver
authored andcommitted
(arxanas#1088) post-rewrite hook does not track intermediate commits from a rebase
1 parent 1fefdaf commit 2880499

File tree

4 files changed

+93
-37
lines changed

4 files changed

+93
-37
lines changed

git-branchless-hook/tests/test_hook.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ fn test_rebase_no_process_new_commits_until_conclusion() -> eyre::Result<()> {
105105
insta::assert_snapshot!(stdout, @"");
106106
}
107107

108-
git.commit_file("test4", 4)?;
109108
{
110109
let (stdout, stderr) = git.run(&["rebase", "--continue"])?;
111110
insta::assert_snapshot!(stderr, @r###"
@@ -133,8 +132,6 @@ fn test_rebase_no_process_new_commits_until_conclusion() -> eyre::Result<()> {
133132
O f777ecc (master) create initial.txt
134133
|\
135134
| o 047b7ad create test1.txt
136-
| |
137-
| o ecab41f create test4.txt
138135
|
139136
x 62fc20d (rewritten as 047b7ad7) create test1.txt
140137
|

git-branchless-lib/src/core/rewrite/rewrite_hooks.rs

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
use std::collections::{HashMap, HashSet};
44

55
use std::fmt::Write;
6-
use std::fs::{self, File};
7-
use std::io::{self, stdin, BufRead, BufReader, Read, Write as WriteIo};
6+
use std::fs::File;
7+
use std::io::{stdin, BufRead, BufReader, Read, Write as WriteIo};
88
use std::path::{Path, PathBuf};
9-
use std::str::FromStr;
109
use std::time::SystemTime;
1110

1211
use console::style;
@@ -44,20 +43,6 @@ pub fn get_deferred_commits_path(repo: &Repo) -> PathBuf {
4443
repo.get_rebase_state_dir_path().join("deferred-commits")
4544
}
4645

47-
fn read_deferred_commits(repo: &Repo) -> eyre::Result<Vec<NonZeroOid>> {
48-
let deferred_commits_path = get_deferred_commits_path(repo);
49-
let contents = match fs::read_to_string(&deferred_commits_path) {
50-
Ok(contents) => contents,
51-
Err(err) if err.kind() == io::ErrorKind::NotFound => Default::default(),
52-
Err(err) => {
53-
return Err(err)
54-
.with_context(|| format!("Reading deferred commits at {deferred_commits_path:?}"))
55-
}
56-
};
57-
let commit_oids = contents.lines().map(NonZeroOid::from_str).try_collect()?;
58-
Ok(commit_oids)
59-
}
60-
6146
#[instrument(skip(stream))]
6247
fn read_rewritten_list_entries(
6348
stream: &mut impl Read,
@@ -148,19 +133,6 @@ pub fn hook_post_rewrite(
148133
let event_log_db = EventLogDb::new(&conn)?;
149134
let event_tx_id = event_log_db.make_transaction_id(now, "hook-post-rewrite")?;
150135

151-
{
152-
let deferred_commit_oids = read_deferred_commits(&repo)?;
153-
let commit_events = deferred_commit_oids
154-
.into_iter()
155-
.map(|commit_oid| Event::CommitEvent {
156-
timestamp,
157-
event_tx_id,
158-
commit_oid,
159-
})
160-
.collect_vec();
161-
event_log_db.add_events(commit_events)?;
162-
}
163-
164136
let (rewritten_oids, rewrite_events) = {
165137
let rewritten_oids = read_rewritten_list_entries(&mut stdin().lock())?;
166138
let events = rewritten_oids

git-branchless-lib/src/testing.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -536,14 +536,15 @@ then you can only run tests in the main `git-branchless` and \
536536
/// hash. The filename is always appended to the message prefix.
537537
#[track_caller]
538538
#[instrument]
539-
pub fn commit_file_with_contents_and_message(
539+
pub fn commit_file_with_contents_and_message_and_file_name(
540540
&self,
541541
name: &str,
542542
time: isize,
543543
contents: &str,
544544
message_prefix: &str,
545+
file_name: &str,
545546
) -> eyre::Result<NonZeroOid> {
546-
let message = format!("{message_prefix} {name}.txt");
547+
let message = format!("{message_prefix} {file_name}");
547548
self.write_file_txt(name, contents)?;
548549
self.run(&["add", "."])?;
549550
self.run_with_options(
@@ -562,6 +563,26 @@ then you can only run tests in the main `git-branchless` and \
562563
Ok(oid)
563564
}
564565

566+
/// Commit a file with given contents and message. The `time` argument is
567+
/// used to set the commit timestamp, which is factored into the commit
568+
/// hash. The filename is always appended to the message prefix.
569+
#[instrument]
570+
pub fn commit_file_with_contents_and_message(
571+
&self,
572+
name: &str,
573+
time: isize,
574+
contents: &str,
575+
message_prefix: &str,
576+
) -> eyre::Result<NonZeroOid> {
577+
self.commit_file_with_contents_and_message_and_file_name(
578+
name,
579+
time,
580+
contents,
581+
message_prefix,
582+
format!("{name}.txt").as_str(),
583+
)
584+
}
585+
565586
/// Commit a file with given contents and a default message. The `time`
566587
/// argument is used to set the commit timestamp, which is factored into the
567588
/// commit hash.
@@ -925,6 +946,18 @@ pub mod pty {
925946
branchless_subcommand: &str,
926947
args: &[&str],
927948
inputs: &[PtyAction],
949+
) -> eyre::Result<ExitStatus> {
950+
// add "branchless" to subcommand list
951+
run_in_pty_with_command(git, &["branchless", branchless_subcommand], args, inputs)
952+
}
953+
954+
/// Run the provided script in the context of a virtual terminal.
955+
#[track_caller]
956+
pub fn run_in_pty_with_command(
957+
git: &Git,
958+
command: &[&str],
959+
args: &[&str],
960+
inputs: &[PtyAction],
928961
) -> eyre::Result<ExitStatus> {
929962
// Use the native pty implementation for the system
930963
let pty_system = native_pty_system();
@@ -944,8 +977,7 @@ pub mod pty {
944977
cmd.env(k, v);
945978
}
946979
cmd.env("TERM", "xterm");
947-
cmd.arg("branchless");
948-
cmd.arg(branchless_subcommand);
980+
cmd.args(command);
949981
cmd.args(args);
950982
cmd.cwd(&git.repo_path);
951983

git-branchless/tests/test_hooks.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ use lib::core::eventlog::{Event, EventLogDb, EventReplayer};
55
use lib::core::formatting::Glyphs;
66
use lib::git::GitVersion;
77
use lib::testing::make_git;
8+
use lib::testing::pty::{run_in_pty_with_command, PtyAction};
89
use lib::util::get_sh;
910
use std::process::Command;
1011

12+
const CARRIAGE_RETURN: &str = "\r";
13+
1114
#[test]
1215
fn test_abandoned_commit_message() -> eyre::Result<()> {
1316
let git = make_git()?;
@@ -411,5 +414,57 @@ fn test_symbolic_transaction_ref() -> eyre::Result<()> {
411414
branchless: processing checkout
412415
"###);
413416
}
417+
418+
Ok(())
419+
}
420+
421+
#[cfg(unix)]
422+
#[test]
423+
fn test_git_rebase_multiple_fixup_does_not_strand_commits() -> eyre::Result<()> {
424+
let git = make_git()?;
425+
git.init_repo()?;
426+
427+
git.detach_head()?;
428+
git.commit_file_with_contents_and_message_and_file_name(
429+
"test1",
430+
1,
431+
"bleh",
432+
"create",
433+
"test1.txt",
434+
)?;
435+
git.commit_file_with_contents_and_message_and_file_name(
436+
"test2",
437+
2,
438+
"bleh",
439+
"fixup! create",
440+
"test1.txt",
441+
)?;
442+
git.commit_file_with_contents_and_message_and_file_name(
443+
"test3",
444+
3,
445+
"bleh",
446+
"fixup! create",
447+
"test1.txt",
448+
)?;
449+
450+
run_in_pty_with_command(
451+
&git,
452+
&["rebase"],
453+
&["-i", "--autosquash", "master"],
454+
&[
455+
PtyAction::WaitUntilContains(" "),
456+
PtyAction::Write(CARRIAGE_RETURN),
457+
],
458+
)?;
459+
460+
{
461+
let stdout = git.smartlog()?;
462+
insta::assert_snapshot!(stdout, @r###"
463+
O f777ecc (master) create initial.txt
464+
|
465+
@ 916a41f create test1.txt
466+
"###);
467+
}
468+
414469
Ok(())
415470
}

0 commit comments

Comments
 (0)