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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
//! This crate provides the [`Repository`] abstraction which serves as a hub into all the functionality of git.
//!
//! It's powerful and won't sacrifice performance while still increasing convenience compared to using the sub-crates
//! individually. Sometimes it may hide complexity under the assumption that the performance difference doesn't matter
//! for all but the fewest tools out there, which would be using the underlying crates directly or file an issue.
//!
//! ## Example
//!
//! This is merely an introduction, for more see the respective [`Repository`] methods.
//! ```
//! # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
//! # mod doctest { include!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/doctest.rs")); }
//! # let repo_dir = doctest::basic_repo_dir()?;
//! # let repo = doctest::open_repo(repo_dir)?;
//! let head = repo.head_commit()?;
//!
//! assert_eq!(repo.head_name()?.expect("born").shorten(), "main");
//! assert_eq!(head.decode()?.message, "c2\n");
//! assert_eq!(repo.head_tree_id()?, head.tree_id()?);
//! # Ok(()) }
//! ```
//!
//! ### The Trust Model
//!
//! It is very simple - based on the ownership of the repository compared to the user of the current process [Trust](sec::Trust)
//! is assigned. This can be [overridden](open::Options::with()) as well. Further, git configuration files track their trust level
//! per section based on and sensitive values like paths to executables or certain values will be skipped if they are from a source
//! that isn't [fully](sec::Trust::Full) trusted.
//!
//! That way, data can safely be obtained without risking to execute untrusted executables.
//!
//! Note that it's possible to let `gix` act like `git` or `git2` by setting the [open::Options::bail_if_untrusted()] option.
//!
//! ### The prelude and extensions
//!
//! With `use git_repository::prelude::*` you should be ready to go as it pulls in various extension traits to make functionality
//! available on objects that may use it.
//!
//! The method signatures are still complex and may require various arguments for configuration and cache control.
//!
//! Most extensions to existing objects provide an `obj_with_extension.attach(&repo).an_easier_version_of_a_method()` for simpler
//! call signatures.
//!
//! ### `ThreadSafe` Mode
//!
//! By default, the [`Repository`] isn't `Sync` and thus can't be used in certain contexts which require the `Sync` trait.
//!
//! To help with this, convert it with [`Repository::into_sync()`] into a [`ThreadSafeRepository`].
//!
//! ### Object-Access Performance
//!
//! Accessing objects quickly is the bread-and-butter of working with git, right after accessing references. Hence it's vital
//! to understand which cache levels exist and how to leverage them.
//!
//! When accessing an object, the first cache that's queried is a memory-capped LRU object cache, mapping their id to data and kind.
//! It has to be specifically enabled on a [`Repository`].
//! On miss, the object is looked up and if a pack is hit, there is a small fixed-size cache for delta-base objects.
//!
//! In scenarios where the same objects are accessed multiple times, the object cache can be useful and is to be configured specifically
//! using the [`Repository::object_cache_size()`] method.
//!
//! Use the `cache-efficiency-debug` cargo feature to learn how efficient the cache actually is - it's easy to end up with lowered
//! performance if the cache is not hit in 50% of the time.
//!
//! ### Terminology
//!
//! #### `WorkingTree` and `WorkTree`
//!
//! When reading the documentation of the canonical gix-worktree program one gets the impression work tree and working tree are used
//! interchangeably. We use the term _work tree_ only and try to do so consistently as its shorter and assumed to be the same.
//!
//! ### Plumbing Crates
//!
//! To make using _sub-crates_ and their types easier, these are re-exported into the root of this crate. Here we list how to access nested plumbing
//! crates which are otherwise harder to discover:
//!
//! **`git_repository::`**
//! * [`odb`]
//! * [`pack`][odb::pack]
//! * [`protocol`]
//! * [`transport`][protocol::transport]
//! * [`packetline`][protocol::transport::packetline]
//!
//! ### `libgit2` API to `gix`
//!
//! This doc-aliases are used to help finding methods under a possibly changed name. Just search in the docs.
//! Entering `git2` into the search field will also surface all methods with such annotations.
//!
//! What follows is a list of methods you might be missing, along with workarounds if available.
//! * [`git2::Repository::open_bare()`](https://docs.rs/git2/*/git2/struct.Repository.html#method.open_bare) ➡ ❌ - use [`open()`] and discard if it is not bare.
//! * [`git2::build::CheckoutBuilder::disable_filters()`](https://docs.rs/git2/*/git2/build/struct.CheckoutBuilder.html#method.disable_filters) ➡ ❌ *(filters are always applied during checkouts)*
//! * [`git2::Repository::submodule_status()`](https://docs.rs/git2/*/git2/struct.Repository.html#method.submodule_status) ➡ [`Submodule::state()`] - status provides more information and conveniences though, and an actual worktree status isn't performed.
//!
//! #### Integrity checks
//!
//! `git2` by default performs integrity checks via [`strict_hash_verification()`](https://docs.rs/git2/latest/git2/opts/fn.strict_hash_verification.html) and
//! [`strict_object_creation`](https://docs.rs/git2/latest/git2/opts/fn.strict_object_creation.html) which `gitoxide` *currently* **does not have**.
//!
//! ### Feature Flags
// Re-exports to make this a potential one-stop shop crate avoiding people from having to reference various crates themselves.
// This also means that their major version changes affect our major version, but that's alright as we directly expose their
// APIs/instances anyway.
pub use gix_actor as actor;
pub use gix_attributes as attrs;
pub use gix_blame as blame;
pub use gix_command as command;
pub use gix_commitgraph as commitgraph;
pub use gix_credentials as credentials;
pub use gix_date as date;
pub use gix_dir as dir;
pub use gix_error as error;
pub use gix_features as features;
use OwnShared;
pub use ;
pub use gix_fs as fs;
pub use gix_glob as glob;
pub use gix_hash as hash;
pub use gix_hashtable as hashtable;
pub use gix_ignore as ignore;
pub use gix_index as index;
pub use gix_lock as lock;
pub use gix_negotiate as negotiate;
pub use gix_object as objs;
pub use bstr;
pub use gix_odb as odb;
pub use gix_prompt as prompt;
pub use gix_protocol as protocol;
pub use gix_ref as refs;
pub use gix_refspec as refspec;
pub use gix_revwalk as revwalk;
pub use gix_sec as sec;
pub use gix_tempfile as tempfile;
pub use gix_trace as trace;
pub use gix_traverse as traverse;
pub use gix_url as url;
pub use Url;
pub use gix_utils as utils;
pub use gix_validate as validate;
pub use ;
pub use ;
///
///
/// The standard type for a store to handle git references.
pub type RefStore = Store;
/// A handle for finding objects in an object database, abstracting away caches for thread-local use.
pub type OdbHandle = Proxy;
/// A handle for finding objects in an object database, abstracting away caches for moving across threads.
pub type OdbHandleArc = Proxy;
/// A way to access git configuration
pub type Config = ;
pub use AttributeStack;
pub use ;
pub use ;
///
///
pub
///
///
///
///
/// Try to open a git repository in `directory` and search upwards through its parents until one is found,
/// using default trust options which matters in case the found repository isn't owned by the current user.
///
/// For details, see [`ThreadSafeRepository::discover()`].
///
/// # Note
///
/// **The discovered repository might not be suitable for any operation that requires authentication with remotes**
/// as it doesn't see the relevant git configuration.
///
/// To achieve that, one has to [enable `git_binary` configuration](https://github.com/GitoxideLabs/gitoxide/blob/9723e1addf52cc336d59322de039ea0537cdca36/src/plumbing/main.rs#L86)
/// in the open-options and use [`ThreadSafeRepository::discover_opts()`] instead. Alternatively, it might be well-known
/// that the tool is going to run in a neatly configured environment without relying on bundled configuration.
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
/// # mod doctest { include!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/doctest.rs")); }
/// # let repo_dir = doctest::basic_repo_dir()?;
/// let repo = doctest::discover_repo(repo_dir.join("some/very/deeply/nested/subdir"))?;
///
/// assert_eq!(repo.kind(), gix::repository::Kind::Common);
/// assert_eq!(repo.head_name()?.expect("born").shorten(), "main");
/// assert!(repo.workdir_path("this").expect("non-bare").is_file());
/// # Ok(()) }
/// ```
/// Try to discover a git repository directly from the environment.
///
/// For details, see [`ThreadSafeRepository::discover_with_environment_overrides_opts()`].
/// Try to open a git repository directly from the environment.
///
/// See [`ThreadSafeRepository::open_with_environment_overrides()`].
/// See [`ThreadSafeRepository::init()`], but returns a [`Repository`] instead.
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
/// # mod doctest { include!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/doctest.rs")); }
/// # let dir = doctest::tempdir()?;
/// let repo = gix::init(dir.path())?;
///
/// assert!(repo.git_dir().is_dir());
/// assert!(repo.head_name()?.is_some());
/// assert!(repo.head()?.is_unborn());
/// # Ok(()) }
/// ```
/// See [`ThreadSafeRepository::init()`], but returns a [`Repository`] instead.
/// Create a platform for configuring a bare clone from `url` to the local `path`, using default options for opening it (but
/// amended with using configuration from the git installation to ensure all authentication options are honored).
///
/// See [`clone::PrepareFetch::new()`] for a function to take full control over all options.
/// Create a platform for configuring a clone with main working tree from `url` to the local `path`, using default options for opening it
/// (but amended with using configuration from the git installation to ensure all authentication options are honored).
///
/// See [`clone::PrepareFetch::new()`] for a function to take full control over all options.
/// See [`ThreadSafeRepository::open()`], but returns a [`Repository`] instead.
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
/// # mod doctest { include!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/doctest.rs")); }
/// # let repo_dir = doctest::basic_repo_dir()?;
/// let repo = doctest::open_repo(repo_dir)?;
///
/// assert_eq!(repo.head_name()?.expect("born").shorten(), "main");
/// assert_eq!(repo.head_commit()?.decode()?.message, "c2\n");
/// # Ok(()) }
/// ```
/// See [`ThreadSafeRepository::open_opts()`], but returns a [`Repository`] instead.
///
///
///
///
///
///
///
/// Not to be confused with 'status'.
///
///
///