Skip to content

Commit ebfb38e

Browse files
committed
feat: Read configuration from git config as well
This makes it much easier to set custom branches for different repos.
1 parent 3341ce3 commit ebfb38e

File tree

2 files changed

+65
-29
lines changed

2 files changed

+65
-29
lines changed

src/lib.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,35 @@ use terminal_size::{terminal_size, Height};
1717

1818
const DEFAULT_UPSTREAM_BRANCHES: &[&str] = &["main", "master", "develop", "trunk"];
1919

20-
pub fn instafix(
21-
squash: bool,
22-
max_commits: usize,
23-
message_pattern: Option<String>,
24-
upstream_branch_name: Option<&str>,
25-
require_newline: bool,
26-
) -> Result<(), anyhow::Error> {
20+
pub struct Config {
21+
/// Change the commit message that you amend, instead of using the original commit message
22+
pub squash: bool,
23+
/// The maximum number of commits to show when looking for your merge point
24+
pub max_commits: usize,
25+
/// Specify a commit to ammend by the subject line of the commit
26+
pub commit_message_pattern: Option<String>,
27+
pub default_upstream_branch: Option<String>,
28+
/// Require a newline when confirming y/n questions
29+
pub require_newline: bool,
30+
}
31+
32+
pub fn instafix(c: Config) -> Result<(), anyhow::Error> {
2733
let repo = Repository::open(".").context("opening repo")?;
28-
let diff = create_diff(&repo, require_newline).context("creating diff")?;
34+
let diff = create_diff(&repo, c.require_newline).context("creating diff")?;
2935
let head = repo.head().context("finding head commit")?;
3036
let head_branch = Branch::wrap(head);
31-
let upstream =
32-
get_merge_base(&repo, &head_branch, upstream_branch_name).context("creating merge base")?;
33-
let commit_to_amend = select_commit_to_amend(&repo, upstream, max_commits, &message_pattern)
34-
.context("selecting commit to amend")?;
37+
let upstream = get_merge_base(&repo, &head_branch, c.default_upstream_branch.as_deref())
38+
.context("creating merge base")?;
39+
let commit_to_amend = select_commit_to_amend(
40+
&repo,
41+
upstream,
42+
c.max_commits,
43+
c.commit_message_pattern.as_deref(),
44+
)
45+
.context("selecting commit to amend")?;
3546
eprintln!("Selected {}", disp(&commit_to_amend));
36-
do_fixup_commit(&repo, &head_branch, &commit_to_amend, squash).context("doing fixup commit")?;
47+
do_fixup_commit(&repo, &head_branch, &commit_to_amend, c.squash)
48+
.context("doing fixup commit")?;
3749
let needs_stash = worktree_is_dirty(&repo)?;
3850
if needs_stash {
3951
// TODO: is it reasonable to create a new repo to work around lifetime issues?
@@ -322,7 +334,7 @@ fn select_commit_to_amend<'a>(
322334
repo: &'a Repository,
323335
upstream: Option<Object<'a>>,
324336
max_commits: usize,
325-
message_pattern: &Option<String>,
337+
message_pattern: Option<&str>,
326338
) -> Result<Commit<'a>, anyhow::Error> {
327339
let mut walker = repo.revwalk()?;
328340
walker.push_head()?;

src/main.rs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ use std::env;
1616

1717
use clap::Parser;
1818

19+
const MAX_COMMITS_VAR: &str = "GIT_INSTAFIX_MAX_COMMITS";
1920
const UPSTREAM_VAR: &str = "GIT_INSTAFIX_UPSTREAM";
20-
const REQUIRE_NEWLINE: &str = "GIT_INSTAFIX_REQUIRE_NEWLINE";
21+
const REQUIRE_NEWLINE_VAR: &str = "GIT_INSTAFIX_REQUIRE_NEWLINE";
2122

2223
#[derive(Parser, Debug)]
2324
#[clap(
@@ -39,36 +40,38 @@ When run with no arguments this will:
3940
)]
4041
struct Args {
4142
/// Change the commit message that you amend, instead of using the original commit message
42-
#[clap(short = 's', long = "squash")]
43-
squash: bool,
43+
#[clap(short = 's', long, hide = true)]
44+
squash: Option<bool>,
4445
/// The maximum number of commits to show when looking for your merge point
45-
#[clap(short = 'm', long = "max-commits", default_value = "15")]
46-
max_commits: usize,
46+
///
47+
/// [gitconfig: instafix.max-commits]
48+
#[clap(short = 'm', long = "max-commits", env = MAX_COMMITS_VAR)]
49+
max_commits: Option<usize>,
4750

4851
/// Specify a commit to ammend by the subject line of the commit
4952
#[clap(short = 'P', long)]
5053
commit_message_pattern: Option<String>,
5154

55+
/// The branch to not go past when looking for your merge point
56+
///
57+
/// [gitconfig: instafix.default-upstream-branch]
5258
#[clap(short = 'u', long, env = UPSTREAM_VAR)]
5359
default_upstream_branch: Option<String>,
5460

5561
/// Require a newline when confirming y/n questions
56-
#[clap(long, env = REQUIRE_NEWLINE)]
57-
require_newline: bool,
62+
///
63+
/// [gitconfig: instafix.require-newline]
64+
#[clap(long, env = REQUIRE_NEWLINE_VAR)]
65+
require_newline: Option<bool>,
5866
}
5967

6068
fn main() {
6169
let mut args = Args::parse();
6270
if env::args().next().unwrap().ends_with("squash") {
63-
args.squash = true
71+
args.squash = Some(true)
6472
}
65-
if let Err(e) = git_instafix::instafix(
66-
args.squash,
67-
args.max_commits,
68-
args.commit_message_pattern,
69-
args.default_upstream_branch.as_deref(),
70-
args.require_newline,
71-
) {
73+
let config = args_to_config_using_git_config(args).unwrap();
74+
if let Err(e) = git_instafix::instafix(config) {
7275
// An empty message means don't display any error message
7376
let msg = e.to_string();
7477
if !msg.is_empty() {
@@ -81,3 +84,24 @@ fn main() {
8184
std::process::exit(1);
8285
}
8386
}
87+
88+
fn args_to_config_using_git_config(args: Args) -> Result<git_instafix::Config, anyhow::Error> {
89+
let mut cfg = git2::Config::open_default()?;
90+
let repo = git2::Repository::discover(".")?;
91+
cfg.add_file(&repo.path().join("config"), git2::ConfigLevel::Local, false)?;
92+
Ok(git_instafix::Config {
93+
squash: args
94+
.squash
95+
.unwrap_or_else(|| cfg.get_bool("instafix.squash").unwrap_or(false)),
96+
max_commits: args
97+
.max_commits
98+
.unwrap_or_else(|| cfg.get_i32("instafix.max-commits").unwrap_or(15) as usize),
99+
commit_message_pattern: args.commit_message_pattern,
100+
default_upstream_branch: args
101+
.default_upstream_branch
102+
.or_else(|| cfg.get_string("instafix.default-upstream-branch").ok()),
103+
require_newline: args
104+
.require_newline
105+
.unwrap_or_else(|| cfg.get_bool("instafix.require-newline").unwrap_or(false)),
106+
})
107+
}

0 commit comments

Comments
 (0)