git-state-0.1.0/.gitignore010066600000000000000000000000101374765301000135310ustar 00000000000000/target git-state-0.1.0/.gitlab-ci.yml010066600000000000000000000041421374765301000142070ustar 00000000000000image: "rust:slim" stages: - check - build - release # Variable defaults variables: RUST_VERSION: stable RUST_TARGET: x86_64-unknown-linux-gnu # Cache rust/cargo/build artifacts cache: key: "$CI_PIPELINE_ID-$RUST_VERSION" paths: - /usr/local/cargo/registry/ - /usr/local/rustup/toolchains/ - /usr/local/rustup/update-hashes/ - target/ # Install compiler and OpenSSL dependencies before_script: - | rustup install $RUST_VERSION rustup default $RUST_VERSION - | rustc --version cargo --version # Check on stable, beta and nightly .check-base: &check-base stage: check script: - cargo check --verbose check-stable: <<: *check-base check-beta: <<: *check-base variables: RUST_VERSION: beta check-nightly: <<: *check-base variables: RUST_VERSION: nightly check-old: <<: *check-base variables: RUST_VERSION: "1.41.0" # Build using Rust stable build-x86_64-linux-gnu: stage: build needs: [] script: - cargo build --target=$RUST_TARGET --release --verbose - mv target/$RUST_TARGET/release/git-state ./git-state-$RUST_TARGET - strip -g ./git-state-$RUST_TARGET artifacts: name: git-state-x86_64-linux-gnu paths: - git-state-$RUST_TARGET expire_in: 1 month # Build a static version build-x86_64-linux-musl: stage: build needs: [] variables: RUST_TARGET: x86_64-unknown-linux-musl script: - rustup target add $RUST_TARGET - cargo build --target=$RUST_TARGET --release --verbose # Prepare the release artifact, strip it - find . -name git-state -exec ls -lah {} \; - mv target/$RUST_TARGET/release/git-state ./git-state-$RUST_TARGET - strip -g ./git-state-$RUST_TARGET artifacts: name: git-state-x86_64-linux-musl paths: - git-state-$RUST_TARGET expire_in: 1 month # Cargo crate release release-crate: stage: release dependencies: [] only: - /^v(\d+\.)*\d+$/ script: - echo "Creating release crate to publish on crates.io..." - echo $CARGO_TOKEN | cargo login - echo "Publishing crate to crates.io..." - cargo publish --verbose --allow-dirty git-state-0.1.0/Cargo.lock0000644000000002141374765305000107530ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "git-state" version = "0.1.0" git-state-0.1.0/Cargo.toml0000644000000016501374765305000110030ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "git-state" version = "0.1.0" authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] description = "Probe git repository state" readme = "README.md" keywords = ["git", "state", "git2"] categories = ["command-line-utilities"] license = "MIT" repository = "https://gitlab.com/timvisee/git-state" [dependencies] [badges.gitlab] branch = "master" repository = "timvisee/git-state" git-state-0.1.0/Cargo.toml.orig010066600000000000000000000007321374765301000144430ustar 00000000000000[package] name = "git-state" version = "0.1.0" authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] license = "MIT" readme = "README.md" # homepage = "https://timvisee.com/projects/git-state" repository = "https://gitlab.com/timvisee/git-state" description = "Probe git repository state" keywords = ["git", "state", "git2"] categories = ["command-line-utilities"] edition = "2018" [badges] gitlab = { repository = "timvisee/git-state", branch = "master" } [dependencies] git-state-0.1.0/LICENSE010066600000000000000000000020371374765301000125610ustar 00000000000000Copyright (c) 2017 Tim Visée Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. git-state-0.1.0/README.md010066600000000000000000000027261374765301000130400ustar 00000000000000[![Build status on GitLab CI][gitlab-ci-master-badge]][gitlab-ci-link] [![Newest release on crates.io][crate-version-badge]][crate-link] [![Documentation][docs-badge]][docs] [![Project license][crate-license-badge]](LICENSE) [crate-license-badge]: https://img.shields.io/crates/l/git-state.svg [crate-link]: https://crates.io/crates/git-state [crate-version-badge]: https://img.shields.io/crates/v/git-state.svg [docs-badge]: https://docs.rs/git-state/badge.svg [docs]: https://docs.rs/git-state [gitlab-ci-link]: https://gitlab.com/timvisee/git-state/pipelines [gitlab-ci-master-badge]: https://gitlab.com/timvisee/git-state/badges/master/pipeline.svg # git-state A simple binary and Rust library to probe the state of a git repository. Useful for shell prompts. This reimplements [`git2::git_repository_state`][git2-function] in pure Rust. This doesn't have any nasty compile or runtime `git2` dependencies. The git command-line interface doesn't provide this functionality. ## States Any of the following state is returned: ``` Clean Merge Revert RevertSequence CherryPick CherryPickSequence Bisect Rebase RebaseInteractive RebaseMerge ApplyMailbox ApplyMailboxOrRebase ``` ## Usage Command-line usage: ```bash cd my-repository/ git-state # or git-state my-repository/ ``` ## License This project is released under the MIT license. Check out the [LICENSE](LICENSE) file for more information. [git2-function]: https://libgit2.org/libgit2/#HEAD/group/repository/git_repository_state git-state-0.1.0/src/lib.rs010066600000000000000000000044311374765301000134570ustar 00000000000000use std::fmt; use std::path::Path; /// Determine the state of a git repository. /// /// This checks whether the progress is in a merging/rebasing/bisecing/etc state. /// If in no such state, `Clean` is returned. /// /// Based on: /// - https://github.com/libgit2/libgit2/blob/52294c413100ed4930764addc69beadd82382a4c/src/repository.c#L2867-L2908 /// - https://libgit2.org/libgit2/#HEAD/group/repository/git_repository_state pub fn git_state(repo: &Path) -> Result { let git_dir = repo.join(".git"); let git_dir = if git_dir.is_dir() { &git_dir } else { repo }; if git_dir.join("rebase-merge/interactive").is_file() { Ok(RepositoryState::RebaseInteractive) } else if git_dir.join("rebase-merge").is_dir() { Ok(RepositoryState::RebaseMerge) } else if git_dir.join("rebase-apply/rebasing").is_file() { Ok(RepositoryState::Rebase) } else if git_dir.join("rebase-apply/applying").is_file() { Ok(RepositoryState::ApplyMailbox) } else if git_dir.join("rebase-apply").is_dir() { Ok(RepositoryState::ApplyMailboxOrRebase) } else if git_dir.join("MERGE_HEAD").is_file() { Ok(RepositoryState::Merge) } else if git_dir.join("REVERT_HEAD").is_file() { if git_dir.join("sequencer/todo").is_file() { Ok(RepositoryState::RevertSequence) } else { Ok(RepositoryState::Revert) } } else if git_dir.join("CHERRY_PICK_HEAD").is_file() { if git_dir.join("sequencer/todo").is_file() { Ok(RepositoryState::CherryPickSequence) } else { Ok(RepositoryState::CherryPick) } } else if git_dir.join("BISECT_LOG").is_file() { Ok(RepositoryState::Bisect) } else { Ok(RepositoryState::Clean) } } /// Git repository state. /// /// Based on: /// - https://libgit2.org/libgit2/#HEAD/type/git_repository_state_t #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum RepositoryState { Clean, Merge, Revert, RevertSequence, CherryPick, CherryPickSequence, Bisect, Rebase, RebaseInteractive, RebaseMerge, ApplyMailbox, ApplyMailboxOrRebase, } impl fmt::Display for RepositoryState { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self) } } git-state-0.1.0/src/main.rs010066600000000000000000000005101374765301000136270ustar 00000000000000use std::env; use git_state; fn main() { let path = match env::current_dir() { Ok(path) => path, Err(_) => env::args() .skip(1) .next() .expect("could not determine git directory") .into(), }; println!("{}", git_state::git_state(&path).unwrap()); }