changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate rust/lib/obj/src/config/repo/hg.rs

changeset 17: c7165d93a9eb
child: 0ccbbd142694
author: ellis <ellis@rwest.io>
date: Sun, 22 Oct 2023 23:03:15 -0400
permissions: -rw-r--r--
description: add obj and net src
17
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
1
 use super::SubRepo;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
2
 use crate::Result;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
3
 use hg_parser::{file_content, FileType, ManifestEntryDetails, MercurialRepository, Revision};
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
4
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
5
 use logger::log::{error, info, trace};
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
6
 use serde::{Deserialize, Serialize};
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
7
 use std::{
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
8
   collections::HashMap,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
9
   fs::File,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
10
   io::{LineWriter, Read, Write},
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
11
   net::SocketAddr,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
12
   path::{Path, PathBuf},
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
13
   time::Instant,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
14
 };
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
15
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
16
 /// Mercurial configuration type -- corresponds to .hgrc file
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
17
 ///
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
18
 /// TODO set 'default' and 'default_push' paths
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
19
 #[derive(Serialize, Deserialize, Debug, PartialEq)]
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
20
 pub struct MercurialConfig {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
21
   pub ui: HashMap<String, String>,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
22
   pub extensions: Option<HashMap<String, Option<String>>>,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
23
   pub paths: Option<HashMap<String, String>>,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
24
   pub web: HgwebConfig,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
25
 }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
26
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
27
 impl MercurialConfig {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
28
   pub fn handle<P: AsRef<Path>>(path: P) -> MercurialRepository {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
29
     MercurialRepository::open(path).unwrap()
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
30
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
31
 }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
32
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
33
 /// Mercurial '.hgsub' file handle, which is just a list of PATH=SOURCE pairs.
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
34
 pub struct HgSubFile {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
35
   pub path: PathBuf,          // path to the .hgsub file
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
36
   pub subrepos: Vec<SubRepo>, // Vec containing `SubRepo` handles
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
37
 }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
38
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
39
 impl HgSubFile {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
40
   /// Create a new '.hgsub' file handle
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
41
   pub fn new() -> Self {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
42
     HgSubFile {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
43
       path: PathBuf::from(".hgsub"),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
44
       subrepos: vec![],
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
45
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
46
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
47
   /// ensure that the path is in a hg repo.
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
48
   fn parent_is_hg(&self) -> bool {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
49
     if self.path.parent().unwrap().join(".hg").exists() {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
50
       true
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
51
     } else {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
52
       false
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
53
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
54
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
55
   /// insert a subrepo into this HgSubFile. does not clone the source
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
56
   /// or ensure that path exists. Takes an optional argument of 'hg'
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
57
   /// or 'git' to indicate the subrepo-type. Value can be ommitted to
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
58
   pub fn insert(&mut self, path: &str, source: &str, vcs: Option<&str>) -> Result<()> {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
59
     let mut prefix = "";
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
60
     // set prefix based on vcs (repo type)
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
61
     if let Some(i) = vcs {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
62
       match i {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
63
         "hg" => prefix = "hg",
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
64
         "git" => prefix = "git",
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
65
         _ => {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
66
           error!("failed to recognize repo type")
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
67
         }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
68
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
69
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
70
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
71
     let source = format!("{}:{}", prefix, source);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
72
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
73
     let subrepo = SubRepo {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
74
       vcs: vcs.unwrap().to_string(),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
75
       origin: source.to_string(),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
76
       path: path.to_string(),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
77
     };
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
78
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
79
     self.subrepos.push(subrepo);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
80
     Ok(())
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
81
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
82
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
83
   /// Save subs to `.hgsub` file specified in the `path` field of
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
84
   /// this struct. This will overwrite any existing file at that path.
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
85
   pub fn save(self) -> Result<()> {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
86
     match self.parent_is_hg() {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
87
       true => {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
88
         let mut file = File::open(self.path).unwrap();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
89
         for i in self.subrepos.iter() {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
90
           write!(file, "{} = {}", i.path, i.origin)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
91
         }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
92
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
93
       false => {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
94
         error!("Parent is not a Mercurial repo!")
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
95
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
96
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
97
     Ok(())
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
98
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
99
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
100
   /// Sort the full contents of a .hgsub file alphabetically.
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
101
   pub fn sort(self) -> Result<Self> {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
102
     let mut fd = File::open(&self.path)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
103
     let len = fd.metadata().unwrap().len() as usize;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
104
     let mut bufr = String::with_capacity(len);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
105
     fd.read_to_string(&mut bufr).unwrap(); // This reads the entire file into memory.
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
106
     drop(fd); // drop the old readonly file descriptor
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
107
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
108
     let mut subs = Vec::new();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
109
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
110
     trace!("starting sort of {:?} lines", &self.path.canonicalize()?);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
111
     for line in bufr.lines() {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
112
       subs.push(line.as_bytes());
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
113
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
114
     subs.sort_unstable();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
115
     trace!("lines have been sorted");
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
116
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
117
     let file = File::create(&self.path)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
118
     let mut file = LineWriter::new(file);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
119
     for sub in subs.iter() {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
120
       file.write_all(sub)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
121
       file.write_all(b"\n")?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
122
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
123
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
124
     file.flush()?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
125
     info!("sorted {:?}", &self.path.canonicalize()?);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
126
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
127
     Ok(self)
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
128
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
129
 }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
130
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
131
 impl Default for HgSubFile {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
132
   fn default() -> Self {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
133
     HgSubFile {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
134
       path: PathBuf::from(".hgsub"),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
135
       subrepos: vec![],
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
136
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
137
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
138
 }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
139
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
140
 /// Hgweb configuration type
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
141
 ///
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
142
 /// Based on the configuration file for 'hgweb' scripts.
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
143
 ///
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
144
 /// We don't store the file path in a field because all HgwebConfig
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
145
 /// values are relative to env::current_dir()
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
146
 #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
147
 pub struct HgwebConfig {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
148
   pub name: String,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
149
   pub contact: String,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
150
   pub description: String,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
151
   pub extensions: Vec<String>,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
152
   pub socket: SocketAddr,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
153
   pub paths: HashMap<PathBuf, PathBuf>,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
154
 }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
155
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
156
 impl Default for HgwebConfig {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
157
   fn default() -> Self {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
158
     HgwebConfig {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
159
       name: "".to_string(),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
160
       contact: "".to_string(),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
161
       description: "".to_string(),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
162
       extensions: vec![],
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
163
       socket: "0.0.0.0:0"
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
164
         .parse()
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
165
         .expect("could not parse hgweb socketaddr"),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
166
       paths: HashMap::new(),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
167
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
168
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
169
 }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
170
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
171
 /// from hg_parser crate docs - given a mercurial repo as a path,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
172
 /// exports to git fast-import format (to stdout)
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
173
 pub fn export_hg_git<P: AsRef<Path>>(path: P) -> Result<()> {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
174
   let start = Instant::now();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
175
   let repo = MercurialRepository::open(path).expect("could not open repo path");
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
176
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
177
   let stdout = std::io::stdout();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
178
   let mut writer = stdout.lock();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
179
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
180
   for changeset in &repo {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
181
     let revision = changeset.revision;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
182
     eprintln!("rev: {:?}", revision);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
183
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
184
     let header = &changeset.header;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
185
     let mut branch = None;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
186
     let mut closed = false;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
187
     for (key, value) in &header.extra {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
188
       if key == b"branch" {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
189
         branch = Some(value.as_slice());
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
190
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
191
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
192
       if key == b"close" && value == b"1" {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
193
         closed = true;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
194
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
195
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
196
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
197
     let mut branch: Vec<_> = branch.unwrap_or_else(|| b"master").into();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
198
     for b in branch.iter_mut() {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
199
       if *b == b' ' {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
200
         *b = b'-';
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
201
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
202
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
203
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
204
     let user = String::from_utf8_lossy(&header.user);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
205
     let desc = String::from_utf8_lossy(&header.comment);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
206
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
207
     let time = header.time.timestamp_secs();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
208
     let timezone = header.time.tz_offset_secs();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
209
     let tz = format!("{:+03}{:02}", -timezone / 3600, ((-timezone % 3600) / 60));
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
210
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
211
     write!(writer, "reset refs/heads/")?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
212
     writer.write_all(&mut branch)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
213
     write!(writer, "\ncommit refs/heads/")?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
214
     writer.write_all(&mut branch)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
215
     writeln!(writer, "\nmark :{}", mark(revision))?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
216
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
217
     writeln!(writer, "author {} {} {}", user, time, tz)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
218
     writeln!(writer, "committer {} {} {}", user, time, tz)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
219
     writeln!(writer, "data {}", desc.len() + 1)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
220
     writeln!(writer, "{}\n", desc)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
221
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
222
     match (header.p1, header.p2) {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
223
       (Some(p1), Some(p2)) => {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
224
         writeln!(writer, "from :{}", mark(p1))?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
225
         writeln!(writer, "merge :{}", mark(p2))?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
226
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
227
       (Some(p), None) | (None, Some(p)) => {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
228
         writeln!(writer, "from :{}", mark(p))?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
229
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
230
       _ => (),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
231
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
232
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
233
     for mut file in changeset.files {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
234
       match (file.data, file.manifest_entry) {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
235
         (None, None) => {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
236
           write!(writer, "D ")?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
237
           writer.write_all(&mut file.path)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
238
           writeln!(writer)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
239
         }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
240
         (Some(data), Some(manifest_entry)) => {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
241
           write!(
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
242
             writer,
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
243
             "M {} inline ",
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
244
             match manifest_entry.details {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
245
               ManifestEntryDetails::File(FileType::Symlink) => "120000",
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
246
               ManifestEntryDetails::File(FileType::Executable) => "100755",
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
247
               ManifestEntryDetails::Tree | ManifestEntryDetails::File(FileType::Regular) =>
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
248
                 "100644",
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
249
             }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
250
           )?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
251
           writer.write_all(&mut file.path)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
252
           let data = file_content(&data);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
253
           writeln!(writer, "\ndata {}", data.len())?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
254
           writer.write_all(&data[..])?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
255
         }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
256
         _ => panic!("Wrong file data!"),
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
257
       }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
258
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
259
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
260
     if closed {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
261
       write!(writer, "reset refs/tags/archive/")?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
262
       writer.write_all(&mut branch)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
263
       writeln!(writer, "\nfrom :{}\n", mark(revision))?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
264
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
265
       write!(writer, "reset refs/heads/")?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
266
       writer.write_all(&mut branch)?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
267
       writeln!(writer, "\nfrom 0000000000000000000000000000000000000000\n")?;
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
268
     }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
269
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
270
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
271
   for (rev, tag) in repo.tags().unwrap() {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
272
     eprintln!("export tag {}", tag.name);
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
273
     writeln!(writer, "reset refs/tags/{}", tag.name).unwrap();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
274
     writeln!(writer, "from :{}", mark(rev)).unwrap();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
275
     writeln!(writer).unwrap();
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
276
   }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
277
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
278
   eprintln!("Done. Elapsed: {:?}", start.elapsed());
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
279
   Ok(())
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
280
 }
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
281
 
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
282
 fn mark<R: Into<Revision>>(rev: R) -> usize {
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
283
   (rev.into() + 1).0 as usize
c7165d93a9eb add obj and net src
ellis <ellis@rwest.io>
parents:
diff changeset
284
 }