]> git.proxmox.com Git - cargo.git/blob - vendor/git2-0.6.11/examples/init.rs
New upstream version 0.24.0
[cargo.git] / vendor / git2-0.6.11 / examples / init.rs
1 /*
2 * libgit2 "init" example - shows how to initialize a new repo
3 *
4 * Written by the libgit2 contributors
5 *
6 * To the extent possible under law, the author(s) have dedicated all copyright
7 * and related and neighboring rights to this software to the public domain
8 * worldwide. This software is distributed without any warranty.
9 *
10 * You should have received a copy of the CC0 Public Domain Dedication along
11 * with this software. If not, see
12 * <http://creativecommons.org/publicdomain/zero/1.0/>.
13 */
14
15 #![deny(warnings)]
16
17 extern crate git2;
18 extern crate docopt;
19 #[macro_use]
20 extern crate serde_derive;
21
22 use docopt::Docopt;
23 use git2::{Repository, RepositoryInitOptions, RepositoryInitMode, Error};
24 use std::path::{PathBuf, Path};
25
26 #[derive(Deserialize)]
27 struct Args {
28 arg_directory: String,
29 flag_quiet: bool,
30 flag_bare: bool,
31 flag_template: Option<String>,
32 flag_separate_git_dir: Option<String>,
33 flag_initial_commit: bool,
34 flag_shared: Option<String>,
35 }
36
37 fn run(args: &Args) -> Result<(), Error> {
38 let mut path = PathBuf::from(&args.arg_directory);
39 let repo = if !args.flag_bare && args.flag_template.is_none() &&
40 args.flag_shared.is_none() &&
41 args.flag_separate_git_dir.is_none() {
42 try!(Repository::init(&path))
43 } else {
44 let mut opts = RepositoryInitOptions::new();
45 opts.bare(args.flag_bare);
46 if let Some(ref s) = args.flag_template {
47 opts.template_path(Path::new(s));
48 }
49
50 // If you specified a separate git directory, then initialize
51 // the repository at that path and use the second path as the
52 // working directory of the repository (with a git-link file)
53 if let Some(ref s) = args.flag_separate_git_dir {
54 opts.workdir_path(&path);
55 path = PathBuf::from(s);
56 }
57
58 if let Some(ref s) = args.flag_shared {
59 opts.mode(try!(parse_shared(s)));
60 }
61 try!(Repository::init_opts(&path, &opts))
62 };
63
64 // Print a message to stdout like "git init" does
65 if !args.flag_quiet {
66 if args.flag_bare || args.flag_separate_git_dir.is_some() {
67 path = repo.path().to_path_buf();
68 } else {
69 path = repo.workdir().unwrap().to_path_buf();
70 }
71 println!("Initialized empty Git repository in {}", path.display());
72 }
73
74 if args.flag_initial_commit {
75 try!(create_initial_commit(&repo));
76 println!("Created empty initial commit");
77 }
78
79 Ok(())
80 }
81
82 /// Unlike regular "git init", this example shows how to create an initial empty
83 /// commit in the repository. This is the helper function that does that.
84 fn create_initial_commit(repo: &Repository) -> Result<(), Error> {
85 // First use the config to initialize a commit signature for the user.
86 let sig = try!(repo.signature());
87
88 // Now let's create an empty tree for this commit
89 let tree_id = {
90 let mut index = try!(repo.index());
91
92 // Outside of this example, you could call index.add_path()
93 // here to put actual files into the index. For our purposes, we'll
94 // leave it empty for now.
95
96 try!(index.write_tree())
97 };
98
99 let tree = try!(repo.find_tree(tree_id));
100
101 // Ready to create the initial commit.
102 //
103 // Normally creating a commit would involve looking up the current HEAD
104 // commit and making that be the parent of the initial commit, but here this
105 // is the first commit so there will be no parent.
106 try!(repo.commit(Some("HEAD"), &sig, &sig, "Initial commit", &tree, &[]));
107
108 Ok(())
109 }
110
111 fn parse_shared(shared: &str) -> Result<RepositoryInitMode, Error> {
112 match shared {
113 "false" | "umask" => Ok(git2::REPOSITORY_INIT_SHARED_UMASK),
114 "true" | "group" => Ok(git2::REPOSITORY_INIT_SHARED_GROUP),
115 "all" | "world" => Ok(git2::REPOSITORY_INIT_SHARED_ALL),
116 _ => {
117 if shared.starts_with('0') {
118 match u32::from_str_radix(&shared[1..], 8).ok() {
119 Some(n) => {
120 Ok(RepositoryInitMode::from_bits_truncate(n))
121 }
122 None => {
123 Err(Error::from_str("invalid octal value for --shared"))
124 }
125 }
126 } else {
127 Err(Error::from_str("unknown value for --shared"))
128 }
129 }
130 }
131 }
132
133 fn main() {
134 const USAGE: &'static str = "
135 usage: init [options] <directory>
136
137 Options:
138 -q, --quiet don't print information to stdout
139 --bare initialize a new bare repository
140 --template <dir> use <dir> as an initialization template
141 --separate-git-dir <dir> use <dir> as the .git directory
142 --initial-commit create an initial empty commit
143 --shared <perms> permissions to create the repository with
144 ";
145
146 let args = Docopt::new(USAGE).and_then(|d| d.deserialize())
147 .unwrap_or_else(|e| e.exit());
148 match run(&args) {
149 Ok(()) => {}
150 Err(e) => println!("error: {}", e),
151 }
152 }