Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ members = [
"git-branchless-reword",
"git-branchless-smartlog",
"git-branchless-test",
"git-branchless-undo",
"git-branchless",
"git-record",
"scm-bisect",
]

[workspace.metadata.release]
Expand Down
9 changes: 9 additions & 0 deletions git-branchless-hook/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
//! The hooks are installed by the `branchless init` command. This module
//! contains the implementations for the hooks.

#![warn(missing_docs)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

use std::fmt::Write;
use std::io::{stdin, BufRead};
use std::time::SystemTime;
Expand Down
29 changes: 24 additions & 5 deletions git-branchless-init/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
//! Install any hooks, aliases, etc. to set up `git-branchless` in this repo.

#![warn(missing_docs)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

use std::fmt::Write;
use std::io::{stdin, stdout, BufRead, BufReader, Write as WriteIo};
use std::path::{Path, PathBuf};
Expand All @@ -21,6 +30,7 @@ use lib::core::eventlog::{EventLogDb, EventReplayer};
use lib::core::repo_ext::RepoExt;
use lib::git::{BranchType, Config, ConfigRead, ConfigWrite, GitRunInfo, GitVersion, Repo};

/// The contents of all Git hooks to install.
pub const ALL_HOOKS: &[(&str, &str)] = &[
(
"post-applypatch",
Expand Down Expand Up @@ -92,15 +102,23 @@ const ALL_ALIASES: &[(&str, &str)] = &[
("unhide", "unhide"),
];

/// A specification for installing a Git hook on disk.
#[derive(Debug)]
pub enum Hook {
/// Regular Git hook.
RegularHook { path: PathBuf },

/// For Twitter multihooks.
MultiHook { path: PathBuf },
RegularHook {
/// The path to the hook script.
path: PathBuf,
},

/// For Twitter multihooks. (But does anyone even work at Twitter anymore?)
MultiHook {
/// The path to the hook script.
path: PathBuf,
},
}

/// Determine the path where all hooks are installed.
#[instrument]
pub fn determine_hook_path(repo: &Repo, hooks_dir: &Path, hook_type: &str) -> eyre::Result<Hook> {
let multi_hooks_path = repo.get_path().join("hooks_multi");
Expand Down Expand Up @@ -638,14 +656,15 @@ fn command_init(

/// Uninstall `git-branchless` in the current repo.
#[instrument]
pub fn command_uninstall(effects: &Effects, git_run_info: &GitRunInfo) -> eyre::Result<ExitCode> {
fn command_uninstall(effects: &Effects, git_run_info: &GitRunInfo) -> eyre::Result<ExitCode> {
let repo = Repo::from_current_dir()?;
let readonly_config = repo.get_readonly_config().wrap_err("Getting repo config")?;
delete_isolated_config(effects, &repo, readonly_config.into_config())?;
uninstall_hooks(effects, git_run_info, &repo)?;
Ok(ExitCode(0))
}

/// Install `git-branchless` in the current repo.
#[instrument]
pub fn command_main(ctx: CommandContext, args: InitArgs) -> eyre::Result<ExitCode> {
let CommandContext {
Expand Down
27 changes: 27 additions & 0 deletions git-branchless-invoke/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
//! This crate is used to invoke `git-branchless` either directly via a
//! subcommand (such as `git-branchless foo`) or via an entirely separate
//! executable (such as `git-branchless-foo`). The objective is to improve
//! developer iteration times by allowing them to build and test a single
//! subcommand in isolation.

#![warn(missing_docs)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

use std::any::Any;
use std::convert::TryInto;
use std::ffi::OsString;
Expand All @@ -24,9 +39,13 @@ use tracing_subscriber::fmt as tracing_fmt;
use tracing_subscriber::prelude::*;
use tracing_subscriber::EnvFilter;

/// Shared context for all commands.
#[derive(Clone, Debug)]
pub struct CommandContext {
/// The `Effects` to use.
pub effects: Effects,

/// Information about the Git executable currently being used.
pub git_run_info: GitRunInfo,
}

Expand Down Expand Up @@ -196,6 +215,14 @@ pub fn do_main_and_drop_locals<T: Parser>(
Ok(exit_code)
}

/// Invoke the provided subcommand main function. This should be used in the
/// `main.rs` file for the subcommand executable. For example:
///
/// ```ignore
/// fn main() {
/// git_branchless_invoke::invoke_subcommand_main(git_branchless_init::command_main)
/// }
/// ```
#[instrument(skip(f))]
pub fn invoke_subcommand_main<T: Parser>(f: impl Fn(CommandContext, T) -> eyre::Result<ExitCode>) {
// Install panic handler.
Expand Down
7 changes: 6 additions & 1 deletion git-branchless-lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
//! Core functionality for git-branchless.

#![warn(missing_docs)]
#![warn(clippy::all, clippy::as_conversions, clippy::clone_on_ref_ptr)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

pub mod core;
Expand Down
7 changes: 6 additions & 1 deletion git-branchless-move/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
//! is also used to preserve merge commits using the `--rebase-merges` option.

#![warn(missing_docs)]
#![warn(clippy::all, clippy::as_conversions, clippy::clone_on_ref_ptr)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

use std::collections::HashMap;
Expand Down
7 changes: 6 additions & 1 deletion git-branchless-navigation/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
//! Convenience commands to help the user move through a stack of commits.

#![warn(missing_docs)]
#![warn(clippy::all, clippy::as_conversions, clippy::clone_on_ref_ptr)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

pub mod prompt;
Expand Down
37 changes: 36 additions & 1 deletion git-branchless-opts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
//! The command-line options for `git-branchless`.

#![warn(missing_docs)]
#![warn(clippy::all, clippy::as_conversions, clippy::clone_on_ref_ptr)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

use clap::{Args, Command as ClapCommand, CommandFactory, Parser, ValueEnum};
Expand Down Expand Up @@ -657,6 +662,22 @@ pub enum TestExecutionStrategy {
Worktree,
}

/// How to conduct searches on the commit graph.
#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum TestSearchStrategy {
/// Visit commits starting from the earliest commit and exit early when a
/// failing commit is found.
Linear,

/// Visit commits starting from the latest commit and exit early when a
/// passing commit is found.
Reverse,

/// Visit commits starting from the middle of the commit graph and exit
/// early when a failing commit is found.
Binary,
}

/// Arguments which apply to all commands. Used during setup.
#[derive(Debug, Parser)]
pub struct GlobalArgs {
Expand Down Expand Up @@ -743,6 +764,20 @@ pub enum TestSubcommand {
#[clap(short = 's', long = "strategy")]
strategy: Option<TestExecutionStrategy>,

/// Search for the first commit that fails the test command, rather than
/// running on all commits.
#[clap(short = 'S', long = "search")]
search: Option<TestSearchStrategy>,

/// Shorthand for `--search binary`.
#[clap(short = 'b', long = "bisect", conflicts_with("search"))]
bisect: bool,

/// Run the test command in the foreground rather than the background so
/// that the user can interact with it.
#[clap(short = 'i', long = "interactive")]
interactive: bool,

/// How many jobs to execute in parallel. The value `0` indicates to use all CPUs.
#[clap(short = 'j', long = "jobs")]
jobs: Option<usize>,
Expand Down
7 changes: 6 additions & 1 deletion git-branchless-record/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
//! Commit changes in the working copy.

#![warn(missing_docs)]
#![warn(clippy::all, clippy::as_conversions, clippy::clone_on_ref_ptr)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

use std::collections::HashSet;
Expand Down
7 changes: 6 additions & 1 deletion git-branchless-revset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
//! Jujutsu.

#![warn(missing_docs)]
#![warn(clippy::all, clippy::as_conversions, clippy::clone_on_ref_ptr)]
#![warn(
clippy::all,
clippy::as_conversions,
clippy::clone_on_ref_ptr,
clippy::dbg_macro
)]
#![allow(clippy::too_many_arguments, clippy::blocks_in_if_conditions)]

mod ast;
Expand Down
Loading