A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/GitoxideLabs/gitoxide/commit/de13b16728f6d29452cb97b50281aa91d498eb49 below:

Merge pull request #1973 from holodorum/feature/blame-range-support · GitoxideLabs/gitoxide@de13b16 · GitHub

1 +

use gix_hash::ObjectId;

2 +

use gix_object::bstr::BString;

3 +

use smallvec::SmallVec;

4 +

use std::ops::RangeInclusive;

1 5

use std::{

2 6

num::NonZeroU32,

3 7

ops::{AddAssign, Range, SubAssign},

4 8

};

5 9 6 -

use gix_hash::ObjectId;

7 -

use gix_object::bstr::BString;

8 -

use smallvec::SmallVec;

9 - 10 10

use crate::file::function::tokens_for_diffing;

11 +

use crate::Error;

12 + 13 +

/// A type to represent one or more line ranges to blame in a file.

14 +

///

15 +

/// It handles the conversion between git's 1-based inclusive ranges and the internal

16 +

/// 0-based exclusive ranges used by the blame algorithm.

17 +

///

18 +

/// # Examples

19 +

///

20 +

/// ```rust

21 +

/// use gix_blame::BlameRanges;

22 +

///

23 +

/// // Blame lines 20 through 40 (inclusive)

24 +

/// let range = BlameRanges::from_range(20..=40);

25 +

///

26 +

/// // Blame multiple ranges

27 +

/// let mut ranges = BlameRanges::new();

28 +

/// ranges.add_range(1..=4); // Lines 1-4

29 +

/// ranges.add_range(10..=14); // Lines 10-14

30 +

/// ```

31 +

///

32 +

/// # Line Number Representation

33 +

///

34 +

/// This type uses 1-based inclusive ranges to mirror `git`'s behaviour:

35 +

/// - A range of `20..=40` represents 21 lines, spanning from line 20 up to and including line 40

36 +

/// - This will be converted to `19..40` internally as the algorithm uses 0-based ranges that are exclusive at the end

37 +

///

38 +

/// # Empty Ranges

39 +

///

40 +

/// An empty `BlameRanges` (created via `BlameRanges::new()` or `BlameRanges::default()`) means

41 +

/// to blame the entire file, similar to running `git blame` without line number arguments.

42 +

#[derive(Debug, Clone, Default)]

43 +

pub struct BlameRanges {

44 +

/// The ranges to blame, stored as 1-based inclusive ranges

45 +

/// An empty Vec means blame the entire file

46 +

ranges: Vec<RangeInclusive<u32>>,

47 +

}

48 + 49 +

/// Lifecycle

50 +

impl BlameRanges {

51 +

/// Create a new empty BlameRanges instance.

52 +

///

53 +

/// An empty instance means to blame the entire file.

54 +

pub fn new() -> Self {

55 +

Self::default()

56 +

}

57 + 58 +

/// Create from a single range.

59 +

///

60 +

/// The range is 1-based, similar to git's line number format.

61 +

pub fn from_range(range: RangeInclusive<u32>) -> Self {

62 +

Self { ranges: vec![range] }

63 +

}

64 + 65 +

/// Create from multiple ranges.

66 +

///

67 +

/// All ranges are 1-based.

68 +

/// Overlapping or adjacent ranges will be merged.

69 +

pub fn from_ranges(ranges: Vec<RangeInclusive<u32>>) -> Self {

70 +

let mut result = Self::new();

71 +

for range in ranges {

72 +

result.merge_range(range);

73 +

}

74 +

result

75 +

}

76 +

}

77 + 78 +

impl BlameRanges {

79 +

/// Add a single range to blame.

80 +

///

81 +

/// The range should be 1-based inclusive.

82 +

/// If the new range overlaps with or is adjacent to an existing range,

83 +

/// they will be merged into a single range.

84 +

pub fn add_range(&mut self, new_range: RangeInclusive<u32>) {

85 +

self.merge_range(new_range);

86 +

}

87 + 88 +

/// Attempts to merge the new range with any existing ranges.

89 +

/// If no merge is possible, add it as a new range.

90 +

fn merge_range(&mut self, new_range: RangeInclusive<u32>) {

91 +

// Check if this range can be merged with any existing range

92 +

for range in &mut self.ranges {

93 +

// Check if ranges overlap or are adjacent

94 +

if new_range.start() <= range.end() && range.start() <= new_range.end() {

95 +

*range = *range.start().min(new_range.start())..=*range.end().max(new_range.end());

96 +

return;

97 +

}

98 +

}

99 +

// If no overlap found, add it as a new range

100 +

self.ranges.push(new_range);

101 +

}

102 + 103 +

/// Convert the 1-based inclusive ranges to 0-based exclusive ranges.

104 +

///

105 +

/// This is used internally by the blame algorithm to convert from git's line number format

106 +

/// to the internal format used for processing.

107 +

///

108 +

/// # Errors

109 +

///

110 +

/// Returns `Error::InvalidLineRange` if:

111 +

/// - Any range starts at 0 (must be 1-based)

112 +

/// - Any range extends beyond the file's length

113 +

/// - Any range has the same start and end

114 +

pub fn to_zero_based_exclusive(&self, max_lines: u32) -> Result<Vec<Range<u32>>, Error> {

115 +

if self.ranges.is_empty() {

116 +

let range = 0..max_lines;

117 +

return Ok(vec![range]);

118 +

}

119 + 120 +

let mut result = Vec::with_capacity(self.ranges.len());

121 +

for range in &self.ranges {

122 +

if *range.start() == 0 {

123 +

return Err(Error::InvalidLineRange);

124 +

}

125 +

let start = range.start() - 1;

126 +

let end = *range.end();

127 +

if start >= max_lines || end > max_lines || start == end {

128 +

return Err(Error::InvalidLineRange);

129 +

}

130 +

result.push(start..end);

131 +

}

132 +

Ok(result)

133 +

}

134 + 135 +

/// Returns true if no specific ranges are set (meaning blame entire file)

136 +

pub fn is_empty(&self) -> bool {

137 +

self.ranges.is_empty()

138 +

}

139 +

}

11 140 12 141

/// Options to be passed to [`file()`](crate::file()).

13 142

#[derive(Default, Debug, Clone)]

14 143

pub struct Options {

15 144

/// The algorithm to use for diffing.

16 145

pub diff_algorithm: gix_diff::blob::Algorithm,

17 -

/// A 1-based inclusive range, in order to mirror `git`’s behaviour. `Some(20..40)` represents

18 -

/// 21 lines, spanning from line 20 up to and including line 40. This will be converted to

19 -

/// `19..40` internally as the algorithm uses 0-based ranges that are exclusive at the end.

20 -

pub range: Option<std::ops::Range<u32>>,

146 +

/// The ranges to blame in the file.

147 +

pub range: BlameRanges,

21 148

/// Don't consider commits before the given date.

22 149

pub since: Option<gix_date::Time>,

23 150

}


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4