summaryrefslogtreecommitdiffstats
path: root/vendor/gix-index/src/extension/resolve_undo.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-index/src/extension/resolve_undo.rs')
-rw-r--r--vendor/gix-index/src/extension/resolve_undo.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/vendor/gix-index/src/extension/resolve_undo.rs b/vendor/gix-index/src/extension/resolve_undo.rs
new file mode 100644
index 000000000..eb6db9ad7
--- /dev/null
+++ b/vendor/gix-index/src/extension/resolve_undo.rs
@@ -0,0 +1,64 @@
+use bstr::BString;
+use gix_hash::ObjectId;
+
+use crate::{
+ extension::Signature,
+ util::{split_at_byte_exclusive, split_at_pos},
+};
+
+pub type Paths = Vec<ResolvePath>;
+
+#[allow(dead_code)]
+#[derive(Clone)]
+pub struct ResolvePath {
+ /// relative to the root of the repository, or what would be stored in the index
+ name: BString,
+
+ /// 0 = ancestor/common, 1 = ours, 2 = theirs
+ stages: [Option<Stage>; 3],
+}
+
+#[allow(dead_code)]
+#[derive(Clone, Copy)]
+pub struct Stage {
+ mode: u32,
+ id: ObjectId,
+}
+
+pub const SIGNATURE: Signature = *b"REUC";
+
+pub fn decode(mut data: &[u8], object_hash: gix_hash::Kind) -> Option<Paths> {
+ let hash_len = object_hash.len_in_bytes();
+ let mut out = Vec::new();
+
+ while !data.is_empty() {
+ let (path, rest) = split_at_byte_exclusive(data, 0)?;
+ data = rest;
+
+ let mut modes = [0u32; 3];
+ for mode in modes.iter_mut() {
+ let (mode_ascii, rest) = split_at_byte_exclusive(data, 0)?;
+ data = rest;
+ *mode = u32::from_str_radix(std::str::from_utf8(mode_ascii).ok()?, 8).ok()?;
+ }
+
+ let mut stages = [None, None, None];
+ for (mode, stage) in modes.iter().zip(stages.iter_mut()) {
+ if *mode == 0 {
+ continue;
+ }
+ let (hash, rest) = split_at_pos(data, hash_len)?;
+ data = rest;
+ *stage = Some(Stage {
+ mode: *mode,
+ id: ObjectId::from(hash),
+ });
+ }
+
+ out.push(ResolvePath {
+ name: path.into(),
+ stages,
+ });
+ }
+ out.into()
+}