summaryrefslogtreecommitdiffstats
path: root/vcx
diff options
context:
space:
mode:
Diffstat (limited to 'vcx')
-rw-r--r--vcx42
1 files changed, 32 insertions, 10 deletions
diff --git a/vcx b/vcx
index 11ba10d..e872961 100644
--- a/vcx
+++ b/vcx
@@ -2,7 +2,6 @@
use strict;
use warnings;
-
use File::Path qw(make_path);
use File::Copy qw(copy);
use File::Find;
@@ -15,9 +14,9 @@ use Digest::SHA qw(sha1_hex);
use POSIX qw(strftime);
use constant VCX_DIR => '.vcx';
-use constant HEAD => VCX_DIR . '/head'; # Current commit ID
-use constant OBJ_DIR => VCX_DIR . '/objs'; # Latest version of a file
-use constant REV_DIR => VCX_DIR . '/revs'; # Commits
+use constant HEAD => VCX_DIR . '/head'; # Current commit ID
+use constant OBJ_DIR => VCX_DIR . '/obj'; # Latest version of a file
+use constant REV_DIR => VCX_DIR . '/rev'; # Commits
# Staging area
use constant TMP_DIR => VCX_DIR . '/index';
@@ -160,10 +159,10 @@ sub run_add {
my $next_id_hex = to_hex_id(from_hex_id($head) + 1);
- my @entries;
+ my %entries;
open my $afh, '>>', TMP_META_FILE or die $!;
- init_stage($latest_tree_dir, \@entries);
+ init_stage($latest_tree_dir, \%entries);
foreach my $input (@targets) {
my @expanded = bsd_glob($input);
@@ -178,7 +177,7 @@ sub run_add {
return if -d $_;
my $rel = $File::Find::name =~ s|^\./||r;
- push @entries, $rel;
+ $entries{$rel} = 1;
my $staged_path = File::Spec->catfile(TMP_TREE, $rel);
my $prev_link = File::Spec->catfile($latest_tree_dir, $rel);
@@ -197,7 +196,7 @@ sub run_add {
my $obj_path = File::Spec->catfile(OBJ_DIR, $obj_name);
if (-e $obj_path) {
- my $p_path = File::Spec->catfile(TMP_DIFF, "$obj_name.$next_id_hex.patch");
+ my $p_path = File::Spec->catfile(TMP_DIFF, "$obj_name.patch");
if (-T $_) {
if (compare($_, $obj_path) != 0) {
unless (-d TMP_DIFF) { make_path(TMP_DIFF); }
@@ -231,9 +230,32 @@ sub run_add {
}, $t);
}
}
+
+ # Pass 2: History -> Workspace (Detects Deletions)
+ foreach my $path (keys %entries) {
+ if (!-e $path && !-l $path) {
+ delete $entries{$path};
+ my $staged_path = File::Spec->catfile(TMP_TREE, $path);
+ if (-e $staged_path || -l $staged_path) {
+ unlink($staged_path) or die "Could not unlink staged $path: $!";
+ my $parent = dirname($staged_path);
+ while ($parent ne TMP_TREE && -d $parent) {
+ last if bsd_glob("$parent/*"); # Stop if not empty
+ rmdir($parent);
+ $parent = dirname($parent);
+ }
+ }
+ print "[D] $path (staged for deletion)\n";
+ }
+ }
+
close $afh;
- my $tree_data = join("\n", sort @entries);
+ my @sorted_paths = sort keys %entries;
+ my $tree_ents = join("\n", @sorted_paths);
+ my $tree_header = "tree " . scalar(@sorted_paths) . "\n";
+ my $tree_data = $tree_header . $tree_ents;
+
my $tree_hash = sha1_hex($tree_data);
my $tree_file = File::Spec->catfile(TMP_DIR, "tree-$tree_hash");
open my $fh, '>', $tree_file or die $!; close $fh;
@@ -514,7 +536,7 @@ sub init_stage {
my $target = readlink($_);
symlink($target, $staged_path) or die "Failed to link $rel: $!";
- push @$entries_ref, $rel;
+ $entries_ref->{$rel} = 1;
},
no_chdir => 1
}, $latest_tree_dir);