Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 34 additions & 38 deletions src/Models/DiffResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,53 +95,45 @@ public TextDiffSelection MakeSelection(int startLine, int endLine, bool isCombin
return rs;
}

public void GenerateNewPatchFromSelection(Change change, string fileBlobGuid, TextDiffSelection selection, bool revert, string output)
public void GenerateNewPatchFromSelection(Change change, string fileBlobGuid, TextDiffSelection selection, string output)
{
var isTracked = !string.IsNullOrEmpty(fileBlobGuid);
var fileGuid = isTracked ? fileBlobGuid : "00000000";

// Collect selected added lines first to check if there's anything to write
var selectedAddedLines = new List<TextDiffLine>();
for (int i = 0; i < Lines.Count; i++)
{
var line = Lines[i];
if (line.Type != TextDiffLineType.Added)
continue;

var lineIndex = i + 1; // 1-based line number
if (lineIndex >= selection.StartLine && lineIndex <= selection.EndLine)
selectedAddedLines.Add(line);
}

if (selectedAddedLines.Count == 0)
return;

using var writer = new StreamWriter(output);
writer.NewLine = "\n";
writer.WriteLine($"diff --git a/{change.Path} b/{change.Path}");
if (!revert && !isTracked)
if (!isTracked)
writer.WriteLine("new file mode 100644");
writer.WriteLine($"index 00000000...{fileGuid}");
writer.WriteLine($"--- {(revert || isTracked ? $"a/{change.Path}" : "/dev/null")}");
writer.WriteLine($"index 0000000..{fileGuid}");
writer.WriteLine($"--- {(isTracked ? $"a/{change.Path}" : "/dev/null")}");
writer.WriteLine($"+++ b/{change.Path}");

var additions = selection.EndLine - selection.StartLine;
if (selection.StartLine != 1)
additions++;

if (revert)
writer.WriteLine($"@@ -0,0 +1,{selectedAddedLines.Count} @@");
foreach (var line in selectedAddedLines)
{
var totalLines = Lines.Count - 1;
writer.WriteLine($"@@ -0,{totalLines - additions} +0,{totalLines} @@");
for (int i = 1; i <= totalLines; i++)
{
var line = Lines[i];
if (line.Type != TextDiffLineType.Added)
continue;

if (i >= selection.StartLine - 1 && i < selection.EndLine)
writer.WriteLine($"+{line.Content}");
else
writer.WriteLine($" {line.Content}");
}
}
else
{
writer.WriteLine($"@@ -0,0 +0,{additions} @@");
for (int i = selection.StartLine - 1; i < selection.EndLine; i++)
{
var line = Lines[i];
if (line.Type != TextDiffLineType.Added)
continue;
writer.WriteLine($"+{line.Content}");
}
writer.WriteLine($"+{line.Content}");
}

writer.WriteLine("\\ No newline at end of file");
if (selectedAddedLines[^1].NoNewLineEndOfFile)
writer.WriteLine("\\ No newline at end of file");

writer.Flush();
}

Expand All @@ -152,7 +144,7 @@ public void GeneratePatchFromSelection(Change change, string fileTreeGuid, TextD
using var writer = new StreamWriter(output);
writer.NewLine = "\n";
writer.WriteLine($"diff --git a/{change.Path} b/{change.Path}");
writer.WriteLine($"index 00000000...{fileTreeGuid} 100644");
writer.WriteLine($"index 0000000..{fileTreeGuid} 100644");
writer.WriteLine($"--- a/{orgFile}");
writer.WriteLine($"+++ b/{change.Path}");

Expand Down Expand Up @@ -255,7 +247,9 @@ public void GeneratePatchFromSelection(Change change, string fileTreeGuid, TextD
}
}

writer.WriteLine($" {tail}");
if (tail != null)
writer.WriteLine($" {tail}");

writer.Flush();
}

Expand All @@ -266,7 +260,7 @@ public void GeneratePatchFromSelectionSingleSide(Change change, string fileTreeG
using var writer = new StreamWriter(output);
writer.NewLine = "\n";
writer.WriteLine($"diff --git a/{change.Path} b/{change.Path}");
writer.WriteLine($"index 00000000...{fileTreeGuid} 100644");
writer.WriteLine($"index 0000000..{fileTreeGuid} 100644");
writer.WriteLine($"--- a/{orgFile}");
writer.WriteLine($"+++ b/{change.Path}");

Expand Down Expand Up @@ -406,7 +400,9 @@ public void GeneratePatchFromSelectionSingleSide(Change change, string fileTreeG
}
}

writer.WriteLine($" {tail}");
if (tail != null)
writer.WriteLine($" {tail}");

writer.Flush();
}

Expand Down
20 changes: 5 additions & 15 deletions src/Views/TextDiffView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1495,7 +1495,7 @@ private async void OnStageChunk(object _1, RoutedEventArgs _2)
var tmpFile = Path.GetTempFileName();
if (change.WorkTree == Models.ChangeState.Untracked)
{
diff.GenerateNewPatchFromSelection(change, null, selection, false, tmpFile);
diff.GenerateNewPatchFromSelection(change, null, selection, tmpFile);
}
else if (chunk.Combined)
{
Expand Down Expand Up @@ -1532,9 +1532,7 @@ private async void OnUnstageChunk(object _1, RoutedEventArgs _2)

var treeGuid = await new Commands.QueryStagedFileBlobGuid(repo.FullPath, change.Path).GetResultAsync();
var tmpFile = Path.GetTempFileName();
if (change.Index == Models.ChangeState.Added)
diff.GenerateNewPatchFromSelection(change, treeGuid, selection, true, tmpFile);
else if (chunk.Combined)
if (chunk.Combined)
diff.GeneratePatchFromSelection(change, treeGuid, selection, true, tmpFile);
else
diff.GeneratePatchFromSelectionSingleSide(change, treeGuid, selection, true, chunk.IsOldSide, tmpFile);
Expand Down Expand Up @@ -1562,20 +1560,12 @@ private async void OnDiscardChunk(object _1, RoutedEventArgs _2)
using var lockWatcher = repo.LockWatcher();

var tmpFile = Path.GetTempFileName();
if (change.Index == Models.ChangeState.Added)
{
diff.GenerateNewPatchFromSelection(change, null, selection, true, tmpFile);
}
else if (chunk.Combined)
{
var treeGuid = await new Commands.QueryStagedFileBlobGuid(repo.FullPath, change.Path).GetResultAsync();
var treeGuid = await new Commands.QueryStagedFileBlobGuid(repo.FullPath, change.Path).GetResultAsync();

if (chunk.Combined)
diff.GeneratePatchFromSelection(change, treeGuid, selection, true, tmpFile);
}
else
{
var treeGuid = await new Commands.QueryStagedFileBlobGuid(repo.FullPath, change.Path).GetResultAsync();
diff.GeneratePatchFromSelectionSingleSide(change, treeGuid, selection, true, chunk.IsOldSide, tmpFile);
}

await new Commands.Apply(repo.FullPath, tmpFile, true, "nowarn", "--reverse").ExecAsync();
File.Delete(tmpFile);
Expand Down
Loading