async_git/config.rs
1use std::io::{Cursor, Error as IOError};
2
3use tokio::io::{AsyncWrite, AsyncWriteExt};
4
5use crate::errors::Result;
6
7#[derive(Clone, Debug, Default)]
8pub struct Config {
9 pub core: CoreConfig,
10}
11
12#[derive(Clone, Debug)]
13pub struct CoreConfig {
14 /// If `true` this repository is assumed to be `bare` and has no working directory associated with it. If this is the case a number of commands that require a working directory will be disabled, such as git-add or git-merge.
15 ///
16 /// This setting is automatically guessed by git-clone or git-init when the repository was created. By default a repository that ends in `/.git` is assumed to be not bare (bare = `false`), while all other repositories are assumed to be bare (bare = `true`).
17 pub bare: bool,
18
19 /// Tells Git if the executable bit of files in the working tree is to be honored.
20 ///
21 /// Some filesystems lose the executable bit when a file that is marked as executable is checked out, or checks out a non-executable file with executable bit on. git-clone or git-init probe the filesystem to see if it handles the executable bit correctly and this variable is automatically set as necessary.
22 ///
23 /// A repository, however, may be on a filesystem that handles the filemode correctly, and this variable is set to `true` when created, but later may be made accessible from another environment that loses the filemode (e.g. exporting ext4 via CIFS mount, visiting a Cygwin created repository with Git for Windows or Eclipse). In such a case it may be necessary to set this variable to `false`. See git-update-index.
24 ///
25 /// The default is `true` (when core.filemode is not specified in the config file).
26 pub file_mode: bool,
27
28 /// Enable the reflog. Updates to a ref `<ref>` is logged to the file `$GIT_DIR/logs/<ref>`, by appending the new and old SHA-1, the date/time and the reason of the update, but only when the file exists. If this configuration variable is set to `true`, missing `$GIT_DIR/logs/<ref>` file is automatically created for branch heads (i.e. under `refs/heads/`), remote refs (i.e. under `refs/remotes/`), note refs (i.e. under `refs/notes/`), and the symbolic ref HEAD. If it is set to always, then a missing reflog is automatically created for any ref under `refs/`.
29 ///
30 /// This information can be used to determine what commit was the tip of a branch "2 days ago".
31 ///
32 /// This value is `true` by default in a repository that has a working directory associated with it, and `false` by default in a bare repository.
33 pub log_all_ref_updates: bool,
34
35 /// Internal variable identifying the repository format and layout version.
36 pub repository_format_version: u32,
37}
38
39impl Default for CoreConfig {
40 fn default() -> Self {
41 CoreConfig {
42 bare: false,
43 file_mode: true,
44 log_all_ref_updates: true,
45 repository_format_version: 0,
46 }
47 }
48}
49
50impl Config {
51 pub async fn parse() -> Result<Self> {
52 Ok(Config::default())
53 }
54
55 pub async fn to_string(self) -> Result<String, IOError> {
56 let mut buffer = Vec::new();
57 let mut cursor = Cursor::new(&mut buffer);
58 self.write(&mut cursor).await?;
59 Ok(String::from_utf8(buffer).unwrap())
60 }
61
62 pub async fn write<W: AsyncWrite + Unpin>(&self, mut w: W) -> Result<(), IOError> {
63 {
64 let core = &self.core;
65 w.write_all(b"[core]\n").await?;
66 w.write_all(format!("bare = {}\n", core.bare).as_bytes())
67 .await?;
68 w.write_all(format!("fileMode = {}\n", core.file_mode).as_bytes())
69 .await?;
70 w.write_all(format!("logAllRefUpdates = {}\n", core.log_all_ref_updates).as_bytes())
71 .await?;
72 w.write_all(
73 format!(
74 "repositoryFormatVersion = {}\n",
75 core.repository_format_version
76 )
77 .as_bytes(),
78 )
79 .await?;
80 }
81 Ok(())
82 }
83}