History

[ref] refactor

Sebastian Thiel committed 5 years ago

Commit 97fc8641 parent f436f184 files · +50 −77Browse files

Unified · Split

4 files
  1. git-ref/src/store/file/transaction.rs +3 −3
  2. git-ref/src/transaction.rs +16 −37
  3. git-ref/tests/file/transaction.rs +10 −11
  4. git-ref/tests/refs.rs +21 −26
git-ref/src/store/file/transaction.rs+3−3
@@ -1,7 +1,7 @@
1use crate::{1use crate::{
2 mutable::Target,2 mutable::Target,
3 store::file,3 store::file,
4 transaction::{Change, DeleteMode, RefEdit, RefEditsExt},4 transaction::{Change, RefEdit, RefEditsExt, RefLogMode},
5};5};
6use bstr::BString;6use bstr::BString;
7use std::io::Write;7use std::io::Write;
@@ -198,8 +198,8 @@ impl<'a> Transaction<'a> { · 190 unmodified lines
198 Change::Delete { mode, .. } => {198 Change::Delete { mode, .. } => {
199 let lock = change.lock.take().expect("each ref is locked, even deletions");199 let lock = change.lock.take().expect("each ref is locked, even deletions");
200 let (rm_reflog, rm_ref) = match mode {200 let (rm_reflog, rm_ref) = match mode {
201 DeleteMode::RefAndRefLog => (true, true),201 RefLogMode::RefAndRefLog => (true, true),
202 DeleteMode::RefLogOnly => (true, false),202 RefLogMode::RefLogOnly => (true, false),
203 };203 };
204 204
205 // Reflog deletion happens first in case it fails a ref without log is less terrible than205 // Reflog deletion happens first in case it fails a ref without log is less terrible than
git-ref/src/transaction.rs+16−37
@@ -37,12 +37,15 @@ pub enum Change { · 36 unmodified lines
37 /// Otherwise it functions as `create-or-update`.37 /// Otherwise it functions as `create-or-update`.
38 Update {38 Update {
39 /// How to treat the reference log.39 /// How to treat the reference log.
40 mode: UpdateMode,40 mode: RefLogMode,
41 /// The previous value of the ref, which will be used to assure the ref is still in the known `previous` state before41 /// The previous value of the ref, which will be used to assure the ref is still in the known `previous` state before
42 /// updating it. It will also be filled in automatically for use in the reflog, if applicable.42 /// updating it. It will also be filled in automatically for use in the reflog, if applicable.
43 previous: Option<Target>,43 previous: Option<Target>,
44 /// The new state of the reference, either for updating an existing one or creating a new one.44 /// The new state of the reference, either for updating an existing one or creating a new one.
45 new: Target,45 new: Target,
46 /// If set, create a reflog even though it would otherwise not be the case as prohibited by general rules.
47 /// Note that ref-log writing might be prohibited in the entire repository which is when this flag has no effect either.
48 force_create_reflog: bool,
46 },49 },
47 /// Delete a reference and optionally check if `previous` is its content.50 /// Delete a reference and optionally check if `previous` is its content.
48 Delete {51 Delete {
@@ -52,7 +55,7 @@ pub enum Change { · 3 unmodified lines
52 /// If a previous ref existed, this value will be filled in automatically and can be accessed if the transaction was committed successfully.55 /// If a previous ref existed, this value will be filled in automatically and can be accessed if the transaction was committed successfully.
53 previous: Option<Target>,56 previous: Option<Target>,
54 /// How to thread the reference log during deletion.57 /// How to thread the reference log during deletion.
55 mode: DeleteMode,58 mode: RefLogMode,
56 },59 },
57}60}
58 61
@@ -70,36 +73,16 @@ pub struct RefEdit { · 11 unmodified lines
70 73
71/// The way to deal with the Reflog in deletions.74/// The way to deal with the Reflog in deletions.
72#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]75#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
73pub enum DeleteMode {76pub enum RefLogMode {
74 /// Delete the reference and the log77 /// Delete the reference and the log
75 RefAndRefLog,78 RefAndRefLog,
76 /// Delete only the reflog79 /// Delete only the reflog
77 RefLogOnly,80 RefLogOnly,
78}81}
79 82
80/// The way to deal with the Reflog in a particular edit
81///
82/// If the `create_unconditionally` field is set, create a reflog even if it otherwise wouldn't be created,
83/// as is the case for tags.
84#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
85pub enum UpdateMode {
86 /// As symbolic references only ever see this when you want to detach them, we won't try to dereference them
87 /// in this case and apply the change to it directly.
88 RefAndRefLog {
89 /// If set, update the reflog even if it otherwise wouldn't.
90 create_unconditionally: bool,
91 },
92 /// Only update the reflog but require this to be a symbolic ref so the actual update can be performed on the
93 /// referent.
94 RefLogOnly {
95 /// If set, update the reflog even if it otherwise wouldn't.
96 create_unconditionally: bool,
97 },
98}
99
100mod ext {83mod ext {
101 use crate::{84 use crate::{
102 transaction::{Change, DeleteMode, RefEdit, Target, UpdateMode},85 transaction::{Change, RefEdit, RefLogMode, Target},
103 RefStore,86 RefStore,
104 };87 };
105 use bstr::BString;88 use bstr::BString;
@@ -162,12 +145,14 @@ mod ext { · 56 unmodified lines
162 deref: true,145 deref: true,
163 },146 },
164 ));147 ));
165 *mode = match *mode {148 *mode = RefLogMode::RefLogOnly;
166 DeleteMode::RefLogOnly => DeleteMode::RefLogOnly,
167 DeleteMode::RefAndRefLog => DeleteMode::RefLogOnly,
168 }
169 }149 }
170 Change::Update { mode, previous, new } => {150 Change::Update {
151 mode,
152 previous,
153 new,
154 force_create_reflog,
155 } => {
171 new_edits.push(make_entry(156 new_edits.push(make_entry(
172 eid,157 eid,
173 RefEdit {158 RefEdit {
@@ -175,19 +160,13 @@ mod ext { · 1 unmodified line
175 previous: previous.clone(),160 previous: previous.clone(),
176 new: new.clone(),161 new: new.clone(),
177 mode: *mode,162 mode: *mode,
163 force_create_reflog: *force_create_reflog,
178 },164 },
179 name: referent,165 name: referent,
180 deref: true,166 deref: true,
181 },167 },
182 ));168 ));
183 *mode = match *mode {169 *mode = RefLogMode::RefLogOnly;
184 UpdateMode::RefLogOnly { create_unconditionally } => {
185 UpdateMode::RefLogOnly { create_unconditionally }
186 }
187 UpdateMode::RefAndRefLog { create_unconditionally } => {
188 UpdateMode::RefLogOnly { create_unconditionally }
189 }
190 }
191 }170 }
192 };171 };
193 edit.deref = false;172 edit.deref = false;
git-ref/tests/file/transaction.rs+10−11
@@ -14,7 +14,7 @@ mod prepare_and_commit { · 13 unmodified lines
14 use git_lock::acquire::Fail;14 use git_lock::acquire::Fail;
15 use git_ref::{15 use git_ref::{
16 mutable::Target,16 mutable::Target,
17 transaction::{Change, RefEdit, UpdateMode},17 transaction::{Change, RefEdit, RefLogMode},
18 };18 };
19 use std::{convert::TryInto, path::Path};19 use std::{convert::TryInto, path::Path};
20 20
@@ -47,9 +47,8 @@ mod prepare_and_commit { · 26 unmodified lines
47 let t = store.transaction(47 let t = store.transaction(
48 Some(RefEdit {48 Some(RefEdit {
49 change: Change::Update {49 change: Change::Update {
50 mode: UpdateMode::RefAndRefLog {50 mode: RefLogMode::RefAndRefLog,
51 create_unconditionally: false,51 force_create_reflog: false,
52 },
53 new: Target::Symbolic(referent.try_into()?),52 new: Target::Symbolic(referent.try_into()?),
54 previous: None, // TODO: check failure if it doesn't exist53 previous: None, // TODO: check failure if it doesn't exist
55 },54 },
@@ -94,7 +93,7 @@ mod prepare_and_commit { · 38 unmodified lines
94 use git_ref::{93 use git_ref::{
95 file::WriteReflog,94 file::WriteReflog,
96 mutable::Target,95 mutable::Target,
97 transaction::{Change, DeleteMode, RefEdit},96 transaction::{Change, RefEdit, RefLogMode},
98 };97 };
99 use std::convert::TryInto;98 use std::convert::TryInto;
100 99
@@ -106,7 +105,7 @@ mod prepare_and_commit { · 5 unmodified lines
106 Some(RefEdit {105 Some(RefEdit {
107 change: Change::Delete {106 change: Change::Delete {
108 previous: None,107 previous: None,
109 mode: DeleteMode::RefAndRefLog,108 mode: RefLogMode::RefAndRefLog,
110 },109 },
111 name: "DOES_NOT_EXIST".try_into().unwrap(),110 name: "DOES_NOT_EXIST".try_into().unwrap(),
112 deref: false,111 deref: false,
@@ -126,7 +125,7 @@ mod prepare_and_commit { · 13 unmodified lines
126 Some(RefEdit {125 Some(RefEdit {
127 change: Change::Delete {126 change: Change::Delete {
128 previous: Some(Target::Peeled(ObjectId::null_sha1())),127 previous: Some(Target::Peeled(ObjectId::null_sha1())),
129 mode: DeleteMode::RefAndRefLog,128 mode: RefLogMode::RefAndRefLog,
130 },129 },
131 name: "DOES_NOT_EXIST".try_into().unwrap(),130 name: "DOES_NOT_EXIST".try_into().unwrap(),
132 deref: false,131 deref: false,
@@ -155,7 +154,7 @@ mod prepare_and_commit { · 22 unmodified lines
155 Some(RefEdit {154 Some(RefEdit {
156 change: Change::Delete {155 change: Change::Delete {
157 previous: Some(Target::Peeled(ObjectId::null_sha1())),156 previous: Some(Target::Peeled(ObjectId::null_sha1())),
158 mode: DeleteMode::RefAndRefLog,157 mode: RefLogMode::RefAndRefLog,
159 },158 },
160 name: head.name().into(),159 name: head.name().into(),
161 deref: false,160 deref: false,
@@ -169,7 +168,7 @@ mod prepare_and_commit { · 7 unmodified lines
169 vec![RefEdit {168 vec![RefEdit {
170 change: Change::Delete {169 change: Change::Delete {
171 previous: Some(Target::Symbolic("refs/heads/main".try_into()?)),170 previous: Some(Target::Symbolic("refs/heads/main".try_into()?)),
172 mode: DeleteMode::RefAndRefLog,171 mode: RefLogMode::RefAndRefLog,
173 },172 },
174 name: head.name().into(),173 name: head.name().into(),
175 deref: false174 deref: false
@@ -196,7 +195,7 @@ mod prepare_and_commit { · 20 unmodified lines
196 Some(RefEdit {195 Some(RefEdit {
197 change: Change::Delete {196 change: Change::Delete {
198 previous: Some(Target::Symbolic("refs/heads/main".try_into()?)),197 previous: Some(Target::Symbolic("refs/heads/main".try_into()?)),
199 mode: DeleteMode::RefLogOnly,198 mode: RefLogMode::RefLogOnly,
200 },199 },
201 name: head.name().into(),200 name: head.name().into(),
202 deref: false,201 deref: false,
@@ -230,7 +229,7 @@ mod prepare_and_commit { · 27 unmodified lines
230 Some(RefEdit {229 Some(RefEdit {
231 change: Change::Delete {230 change: Change::Delete {
232 previous: Some(Target::Symbolic("refs/heads/main".try_into().unwrap())),231 previous: Some(Target::Symbolic("refs/heads/main".try_into().unwrap())),
233 mode: DeleteMode::RefLogOnly,232 mode: RefLogMode::RefLogOnly,
234 },233 },
235 name: head.name().into(),234 name: head.name().into(),
236 deref: true,235 deref: true,
git-ref/tests/refs.rs+21−26
@@ -3,14 +3,14 @@ type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>; · 2 unmodified lines
3mod file;3mod file;
4mod transaction {4mod transaction {
5 mod refedit_ext {5 mod refedit_ext {
6 use git_ref::transaction::{Change, DeleteMode, RefEdit, RefEditsExt};6 use git_ref::transaction::{Change, RefEdit, RefEditsExt, RefLogMode};
7 use std::convert::TryInto;7 use std::convert::TryInto;
8 8
9 fn named_edit(name: &str) -> RefEdit {9 fn named_edit(name: &str) -> RefEdit {
10 RefEdit {10 RefEdit {
11 change: Change::Delete {11 change: Change::Delete {
12 previous: None,12 previous: None,
13 mode: DeleteMode::RefAndRefLog,13 mode: RefLogMode::RefAndRefLog,
14 },14 },
15 name: name.try_into().expect("valid name"),15 name: name.try_into().expect("valid name"),
16 deref: false,16 deref: false,
@@ -43,7 +43,7 @@ mod transaction { · 26 unmodified lines
43 use git_hash::ObjectId;43 use git_hash::ObjectId;
44 use git_ref::{44 use git_ref::{
45 mutable::Target,45 mutable::Target,
46 transaction::{Change, DeleteMode, RefEdit, RefEditsExt, UpdateMode},46 transaction::{Change, RefEdit, RefEditsExt, RefLogMode},
47 FullName, PartialName, RefStore,47 FullName, PartialName, RefStore,
48 };48 };
49 use git_testtools::hex_to_id;49 use git_testtools::hex_to_id;
@@ -99,7 +99,7 @@ mod transaction { · 49 unmodified lines
99 RefEdit {99 RefEdit {
100 change: Change::Delete {100 change: Change::Delete {
101 previous: None,101 previous: None,
102 mode: DeleteMode::RefAndRefLog,102 mode: RefLogMode::RefAndRefLog,
103 },103 },
104 name: "SYMBOLIC_PROBABLY_BUT_DEREF_IS_FALSE_SO_IGNORED".try_into()?,104 name: "SYMBOLIC_PROBABLY_BUT_DEREF_IS_FALSE_SO_IGNORED".try_into()?,
105 deref: false,105 deref: false,
@@ -107,7 +107,7 @@ mod transaction { · 1 unmodified line
107 RefEdit {107 RefEdit {
108 change: Change::Delete {108 change: Change::Delete {
109 previous: None,109 previous: None,
110 mode: DeleteMode::RefAndRefLog,110 mode: RefLogMode::RefAndRefLog,
111 },111 },
112 name: "refs/heads/anything-but-not-symbolic".try_into()?,112 name: "refs/heads/anything-but-not-symbolic".try_into()?,
113 deref: true,113 deref: true,
@@ -115,7 +115,7 @@ mod transaction { · 1 unmodified line
115 RefEdit {115 RefEdit {
116 change: Change::Delete {116 change: Change::Delete {
117 previous: None,117 previous: None,
118 mode: DeleteMode::RefAndRefLog,118 mode: RefLogMode::RefAndRefLog,
119 },119 },
120 name: "refs/heads/does-not-exist-and-deref-is-ignored".try_into()?,120 name: "refs/heads/does-not-exist-and-deref-is-ignored".try_into()?,
121 deref: true,121 deref: true,
@@ -167,7 +167,7 @@ mod transaction { · 45 unmodified lines
167 RefEdit {167 RefEdit {
168 change: Change::Delete {168 change: Change::Delete {
169 previous: None,169 previous: None,
170 mode: DeleteMode::RefAndRefLog,170 mode: RefLogMode::RefAndRefLog,
171 },171 },
172 name: "refs/heads/delete-symbolic-1".try_into().unwrap(),172 name: "refs/heads/delete-symbolic-1".try_into().unwrap(),
173 deref: true,173 deref: true,
@@ -175,9 +175,8 @@ mod transaction { · 1 unmodified line
175 RefEdit {175 RefEdit {
176 change: Change::Update {176 change: Change::Update {
177 previous: None,177 previous: None,
178 mode: UpdateMode::RefAndRefLog {178 mode: RefLogMode::RefAndRefLog,
179 create_unconditionally: true,179 force_create_reflog: true,
180 },
181 new: Target::Peeled(ObjectId::null_sha1()),180 new: Target::Peeled(ObjectId::null_sha1()),
182 },181 },
183 name: "refs/heads/update-symbolic-1".try_into().unwrap(),182 name: "refs/heads/update-symbolic-1".try_into().unwrap(),
@@ -226,7 +225,7 @@ mod transaction { · 42 unmodified lines
226 RefEdit {225 RefEdit {
227 change: Change::Delete {226 change: Change::Delete {
228 previous: None,227 previous: None,
229 mode: DeleteMode::RefAndRefLog,228 mode: RefLogMode::RefAndRefLog,
230 },229 },
231 name: "refs/heads/delete-symbolic-1".try_into().unwrap(),230 name: "refs/heads/delete-symbolic-1".try_into().unwrap(),
232 deref: true,231 deref: true,
@@ -234,9 +233,8 @@ mod transaction { · 1 unmodified line
234 RefEdit {233 RefEdit {
235 change: Change::Update {234 change: Change::Update {
236 previous: None,235 previous: None,
237 mode: UpdateMode::RefAndRefLog {236 mode: RefLogMode::RefAndRefLog,
238 create_unconditionally: true,237 force_create_reflog: true,
239 },
240 new: Target::Peeled(ObjectId::null_sha1()),238 new: Target::Peeled(ObjectId::null_sha1()),
241 },239 },
242 name: "refs/heads/update-symbolic-1".try_into().unwrap(),240 name: "refs/heads/update-symbolic-1".try_into().unwrap(),
@@ -264,7 +262,7 @@ mod transaction { · 21 unmodified lines
264 RefEdit {262 RefEdit {
265 change: Change::Delete {263 change: Change::Delete {
266 previous: None,264 previous: None,
267 mode: DeleteMode::RefLogOnly,265 mode: RefLogMode::RefLogOnly,
268 },266 },
269 name: "refs/heads/delete-symbolic-1".try_into().unwrap(),267 name: "refs/heads/delete-symbolic-1".try_into().unwrap(),
270 deref: false,268 deref: false,
@@ -272,9 +270,8 @@ mod transaction { · 1 unmodified line
272 RefEdit {270 RefEdit {
273 change: Change::Update {271 change: Change::Update {
274 previous: None,272 previous: None,
275 mode: UpdateMode::RefLogOnly {273 mode: RefLogMode::RefLogOnly,
276 create_unconditionally: true,274 force_create_reflog: true,
277 },
278 new: Target::Peeled(ObjectId::null_sha1()),275 new: Target::Peeled(ObjectId::null_sha1()),
279 },276 },
280 name: "refs/heads/update-symbolic-1".try_into().unwrap(),277 name: "refs/heads/update-symbolic-1".try_into().unwrap(),
@@ -283,7 +280,7 @@ mod transaction { · 2 unmodified lines
283 RefEdit {280 RefEdit {
284 change: Change::Delete {281 change: Change::Delete {
285 previous: None,282 previous: None,
286 mode: DeleteMode::RefLogOnly,283 mode: RefLogMode::RefLogOnly,
287 },284 },
288 name: "refs/heads/delete-symbolic-2".try_into().unwrap(),285 name: "refs/heads/delete-symbolic-2".try_into().unwrap(),
289 deref: false,286 deref: false,
@@ -291,9 +288,8 @@ mod transaction { · 1 unmodified line
291 RefEdit {288 RefEdit {
292 change: Change::Update {289 change: Change::Update {
293 previous: None,290 previous: None,
294 mode: UpdateMode::RefLogOnly {291 mode: RefLogMode::RefLogOnly,
295 create_unconditionally: true,292 force_create_reflog: true,
296 },
297 new: Target::Peeled(ObjectId::null_sha1()),293 new: Target::Peeled(ObjectId::null_sha1()),
298 },294 },
299 name: "refs/heads/update-symbolic-2".try_into().unwrap(),295 name: "refs/heads/update-symbolic-2".try_into().unwrap(),
@@ -302,7 +298,7 @@ mod transaction { · 2 unmodified lines
302 RefEdit {298 RefEdit {
303 change: Change::Delete {299 change: Change::Delete {
304 previous: None,300 previous: None,
305 mode: DeleteMode::RefAndRefLog,301 mode: RefLogMode::RefAndRefLog,
306 },302 },
307 name: "refs/heads/delete-symbolic-3".try_into().unwrap(),303 name: "refs/heads/delete-symbolic-3".try_into().unwrap(),
308 deref: false,304 deref: false,
@@ -310,9 +306,8 @@ mod transaction { · 1 unmodified line
310 RefEdit {306 RefEdit {
311 change: Change::Update {307 change: Change::Update {
312 previous: None,308 previous: None,
313 mode: UpdateMode::RefAndRefLog {309 mode: RefLogMode::RefAndRefLog,
314 create_unconditionally: true,310 force_create_reflog: true,
315 },
316 new: Target::Peeled(ObjectId::null_sha1()),311 new: Target::Peeled(ObjectId::null_sha1()),
317 },312 },
318 name: "refs/heads/update-symbolic-3".try_into().unwrap(),313 name: "refs/heads/update-symbolic-3".try_into().unwrap(),