1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// git-bug-rs - A rust library for interfacing with git-bug repositories
//
// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This file is part of git-bug-rs/git-gub.
//
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/agpl.txt>.
//! This crate provides the access to the git-bug data in a repository.
//!
//! Repository access is handled via the [`Replica`][`replica::Replica`]
//! structure. This is also the main entry point to `git-bug-rs`.
//!
//! Beware that `git-bug-rs` currently *cannot* change the `git-bug` data. This
//! is however planned.
//!
//! ### Quickstart
//!
//! #### Basic example
//! The obvious use case of `git-bug-rs` is to read out all issues in a given
//! replica. The following code will do just that.
//!
//! ```no_run
//! # fn do_not_run_only_compile() {
//! use crate::git_bug::replica::entity::Entity;
//!
//! git_bug::replica::Replica::from_path(".")
//! .unwrap()
//! .get_all::<git_bug::entities::issue::Issue>()
//! .unwrap()
//! .map(|maybe_issue| maybe_issue.unwrap().unwrap().snapshot())
//! .for_each(|issue_snapshot| println!("{}", issue_snapshot.title()));
//! # }
//! ```
//!
//! Notice, how we first constructed an
//! iterator over the
//! [`Issues`][`entities::issue::Issue`].
//! Each [`Entity`][`replica::entity::Entity`] contains only their composing
//! [`Operations`][`replica::entity::operation::operations::Operations`], to get
//! the actual final value (in this case the titles), we first needed to
//! [create][replica::entity::Entity::snapshot] a
//! [snapshot][replica::entity::snapshot::Snapshot].
//!
//! This snapshot contains the full history of this specific
//! [`Entity`][`replica::entity::Entity`] up to the point it was taken. It can
//! be used to display the full history, e.g., when creating something similar
//! to GitHub's issue timeline, or to calculate the final value.
//!
//! #### Working with the [`HistorySteps`][`HistoryStep`] in a [`Snapshot`]
//!
//! This will print out all the changes of an
//! [`Identity's`][`entities::identity::Identity`] name and the id of the
//! [`Identity`][`entities::identity::Identity`] that performed that change.
//!
//! ```no_run
//! use crate::git_bug::replica::entity::Entity;
//!
//! # fn do_not_run_only_compile() -> Result<(), Box<dyn std::error::Error>> {
//! let replica = git_bug::replica::Replica::from_path(".")?;
//! replica
//! .get_all::<git_bug::entities::identity::Identity>()?
//! .map(|maybe_identity| maybe_identity.unwrap().unwrap().snapshot())
//! .for_each(|identity_snapshot| {
//! identity_snapshot
//! .timeline()
//! .name_history()
//! .for_each(|name_history_step| {
//! println!(
//! "{} changed the name of this identity to '{}'",
//! replica
//! .get::<git_bug::entities::identity::Identity>(
//! name_history_step.author.id()
//! )
//! .unwrap()
//! .snapshot(),
//! name_history_step.name
//! );
//! });
//! });
//! # Ok(())
//! # }
//! ```
//!
//! ### Terminology
//!
//! #### `git-bug`
//!
//! Will mostly refer to the original go implementation of `git-bug`.
//! `git-bug-rs` refers to this crate and `git-gub` to our own command line tool
//! for interacting with `git-bug` repositories.
//!
//! #### `Issue`
//!
//! While `git-bug` refers to the data chains
//! (DAGs) as “Bugs”, we refer to them as “Issues”.
//! This makes the terminology clearer, as not every Issue is necessarily a bug (e.g., a feature
//! request), whilst every bug is an issue.
//!
//! ## Serde support
//!
//! You will notice, that many types implement serde's Serialize and Deserialize traits.
//! This is an unfortunate side effect of having to use serde for the cache de-/serialization.
//! Some of these implies allow you to circumvent type invariants, as such, using them is not
//! supported and they should be treated as implementation detail.
//!
//! Once, bitcode gets its `#[bitcode(with_serde)]` attribute back, we will probably migrate to
//! that.
// //! ### Feature Flags
// #![cfg_attr(
// doc,
// doc = ::document_features::document_features!()
// )]
// #![cfg_attr(doc, feature(doc_cfg, doc_auto_cfg))]
// Needed for the doc comment above.
use ;