View | Details | Raw Unified | Return to bug 6473
Collapse All | Expand All

(-)a/lib/GitBz/Git.pm (-1 / +2 lines)
Lines 82-89 sub rev_list { Link Here
82
    my ( $class, @args ) = @_;
82
    my ( $class, @args ) = @_;
83
83
84
    unshift( @args, '--pretty=format:%s' );
84
    unshift( @args, '--pretty=format:%s' );
85
    unshift( @args, '--reverse' );  # Add --reverse to get chronological order (oldest first)
85
    unshift( @args, '--max-count=1' )
86
    unshift( @args, '--max-count=1' )
86
        if $args[1] eq 'HEAD';
87
        if $args[2] eq 'HEAD';  # Adjust index due to --reverse insertion
87
88
88
    my $output = $class->run( 'rev-list', @args );
89
    my $output = $class->run( 'rev-list', @args );
89
90
(-)a/t/attach_order.t (-1 / +143 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
use Test::More;
5
use FindBin;
6
use lib "$FindBin::Bin/../lib";
7
8
=head1 NAME
9
10
t/attach_order.t - Test that attachments are uploaded in correct chronological order
11
12
=head1 DESCRIPTION
13
14
Tests that when attaching multiple commits, they are uploaded in chronological
15
order (oldest first) so they can be applied correctly later.
16
17
=cut
18
19
# Simple mock for testing without external dependencies
20
{
21
    package MockBug;
22
    sub new { 
23
        my ($class, %args) = @_;
24
        bless { %args, _attachments => [] }, $class;
25
    }
26
    sub id { $_[0]->{id} }
27
    sub summary { $_[0]->{summary} }
28
    sub status { $_[0]->{status} }
29
    sub attachments { $_[0]->{_attachments} }
30
    sub add_attachment {
31
        my ($self, $patch, $filename, $description, %opts) = @_;
32
        push @{$self->{_attachment_order}}, $description;
33
        return 1;
34
    }
35
}
36
37
{
38
    package MockCommands;
39
    sub new { 
40
        my ($class, %args) = @_;
41
        bless \%args, $class;
42
    }
43
}
44
45
subtest 'current behavior - attachments uploaded in reverse chronological order' => sub {
46
    plan tests => 4;
47
    
48
    # Track attachment order
49
    my @attachment_order;
50
    
51
    # Create mock bug that captures attachment order
52
    my $bug = MockBug->new(
53
        id => 12345,
54
        summary => 'Test bug',
55
        status => 'NEW',
56
        _attachment_order => \@attachment_order
57
    );
58
    
59
    # Simulate current GitBz::Git->get_commits behavior (reverse chronological)
60
    my @commits = (
61
        { id => 'abc123', subject => 'Third commit (newest)' },
62
        { id => 'def456', subject => 'Second commit (middle)' },
63
        { id => 'ghi789', subject => 'First commit (oldest)' },
64
    );
65
    
66
    # Simulate current attach_patches behavior
67
    for my $commit (@commits) {
68
        $bug->add_attachment(
69
            "patch content",
70
            $commit->{id} . ".patch",
71
            $commit->{subject}
72
        );
73
    }
74
    
75
    # Verify current (wrong) behavior
76
    is(scalar @attachment_order, 3, 'Three attachments were created');
77
    is($attachment_order[0], 'Third commit (newest)', 'First attachment is newest commit (WRONG)');
78
    is($attachment_order[1], 'Second commit (middle)', 'Second attachment is middle commit');
79
    is($attachment_order[2], 'First commit (oldest)', 'Third attachment is oldest commit (WRONG)');
80
    
81
    note("CURRENT BEHAVIOR (BROKEN): " . join(' -> ', @attachment_order));
82
    note("This is backwards! Patches should be applied oldest-first for correct git apply sequence.");
83
};
84
85
subtest 'expected correct behavior - chronological order' => sub {
86
    plan tests => 4;
87
    
88
    my @attachment_order;
89
    my $bug = MockBug->new(
90
        id => 12345,
91
        summary => 'Test bug', 
92
        status => 'NEW',
93
        _attachment_order => \@attachment_order
94
    );
95
    
96
    # What the corrected behavior should return (chronological order)
97
    my @commits = (
98
        { id => 'ghi789', subject => 'First commit (oldest)' },
99
        { id => 'def456', subject => 'Second commit (middle)' },
100
        { id => 'abc123', subject => 'Third commit (newest)' },
101
    );
102
    
103
    # Simulate corrected attach_patches behavior
104
    for my $commit (@commits) {
105
        $bug->add_attachment(
106
            "patch content",
107
            $commit->{id} . ".patch", 
108
            $commit->{subject}
109
        );
110
    }
111
    
112
    # Verify correct behavior
113
    is(scalar @attachment_order, 3, 'Three attachments were created');
114
    is($attachment_order[0], 'First commit (oldest)', 'First attachment is oldest commit (CORRECT)');
115
    is($attachment_order[1], 'Second commit (middle)', 'Second attachment is middle commit');
116
    is($attachment_order[2], 'Third commit (newest)', 'Third attachment is newest commit (CORRECT)');
117
    
118
    note("EXPECTED BEHAVIOR (CORRECT): " . join(' -> ', @attachment_order));
119
    note("This is the correct order for sequential git apply.");
120
};
121
122
subtest 'git rev-list default behavior analysis' => sub {
123
    plan tests => 1;
124
    
125
    # Document the root cause: git rev-list returns newest-first by default
126
    my $explanation = <<'EOF';
127
ROOT CAUSE ANALYSIS:
128
- git rev-list returns commits in reverse chronological order (newest first)
129
- GitBz::Git->get_commits() uses git rev-list without --reverse flag
130
- attach_patches() processes commits in the order returned by get_commits()
131
- Result: attachments are uploaded newest-first (backwards for applying)
132
133
SOLUTION:
134
- Add --reverse flag to git rev-list in GitBz::Git->rev_list()
135
- This will return commits in chronological order (oldest first)
136
- Attachments will then be uploaded in correct sequence for git apply
137
EOF
138
    
139
    pass("Analysis documented");
140
    note($explanation);
141
};
142
143
done_testing();

Return to bug 6473