Skip to content

Fix Discard of deleted files #689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 22, 2025
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Embedded Git commits settings when cloning empty repo to avert any issues
- Fixed Import All options not importing the Embedded Git configuration file
- Improved performance of IDE editing and baselining of decomposed productions
- Fixed Discard / Stash not working on deletes (#688)

## [2.9.0] - 2025-01-09

Expand Down
46 changes: 31 additions & 15 deletions cls/SourceControl/Git/DiscardState.cls
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Property Timestamp As %TimeStamp [ Required ];

Property ExternalFile As %Boolean [ Required ];

/// Boolean tracking whether or not file was deleted as part of change
Property Deleted As %Boolean;

Index BranchMap On Branch [ Type = bitmap ];

Method RestoreToFileTree()
Expand All @@ -24,17 +27,22 @@ Method RestoreToFileTree()
if ('##class(%File).DirectoryExists(dir)) {
do ##class(%File).CreateDirectoryChain(dir)
}

if (..Deleted) {
do ##class(%File).Delete(..FullExternalName)
} else {

// Recreate File
set fileStream = ##class(%Stream.FileCharacter).%New()
set fileStream.Filename = ..FullExternalName
$$$ThrowOnError(fileStream.CopyFrom(..Contents))
$$$ThrowOnError(fileStream.%Save())

// Add file to source-control / IRIS
if '..ExternalFile {
do ##class(SourceControl.Git.Utils).ImportItem(..Name, 1, 1, 1)
do ##class(SourceControl.Git.Utils).AddToServerSideSourceControl(..Name)
// Recreate File
set fileStream = ##class(%Stream.FileCharacter).%New()
set fileStream.Filename = ..FullExternalName
$$$ThrowOnError(fileStream.CopyFrom(..Contents))
$$$ThrowOnError(fileStream.%Save())

// Add file to source-control / IRIS
if '..ExternalFile {
do ##class(SourceControl.Git.Utils).ImportItem(..Name, 1, 1, 1)
do ##class(SourceControl.Git.Utils).AddToServerSideSourceControl(..Name)
}
}

// Delete discard record
Expand All @@ -57,11 +65,16 @@ ClassMethod SaveDiscardState(InternalName As %String, name As %String) As %Statu
set discardState.ExternalFile = 0
}
// Copy over file contents
set fileStream = ##class(%Stream.FileCharacter).%New()
set fileStream.Filename = discardState.FullExternalName
do fileStream.%Open()
do discardState.Contents.CopyFrom(fileStream)
do fileStream.%Close()
if (##class(%File).Exists(discardState.FullExternalName)) {
set fileStream = ##class(%Stream.FileCharacter).%New()
set fileStream.Filename = discardState.FullExternalName
do fileStream.%Open()
do discardState.Contents.CopyFrom(fileStream)
do fileStream.%Close()
} else {
set discardState.Deleted = 1
do discardState.Contents.Write("Deleted File")
}

// Save extra information
set discardState.Username = $USERNAME
Expand Down Expand Up @@ -126,6 +139,9 @@ Storage Default
<Value name="9">
<Value>ExternalFile</Value>
</Value>
<Value name="10">
<Value>Deleted</Value>
</Value>
</Data>
<DataLocation>^SourceControl22B9.DiscardStateD</DataLocation>
<DefaultData>DiscardStateDefaultData</DefaultData>
Expand Down
35 changes: 26 additions & 9 deletions git-webui/release/share/git-webui/webui/js/git-webui.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ webui.parseGitResponse = function(data) {
};
}

webui.processGitResponse = function(data, command, callback, warningCallback) {
webui.processGitResponse = function(data, command, callback, warningCallback,errorCallback) {
var result = webui.parseGitResponse(data);
var rcode = result.rcode;
var output = result.output;
Expand Down Expand Up @@ -177,15 +177,20 @@ webui.processGitResponse = function(data, command, callback, warningCallback) {
location.reload();
return false;
}
webui.showError(displayMessage);
if (errorCallback) {
errorCallback(displayMessage);
} else {
webui.showError(displayMessage);
}

//}
} else {
webui.showError("The command <pre>"+command.join(" ")+"</pre> failed because of an unknown reason. Returned response: \n\n"+data)
}
}
}

webui.git_command = function(command, callback, warningCallback) {
webui.git_command = function(command, callback, warningCallback, errorCallback) {
$.ajax({
url: "git-command",
type: "POST",
Expand All @@ -194,11 +199,15 @@ webui.git_command = function(command, callback, warningCallback) {
command: command
}),
success: function(data) {
webui.processGitResponse(data, command, callback, warningCallback);
webui.processGitResponse(data, command, callback, warningCallback, errorCallback);
},
error: function(data) {
var trimmedData = data.replace(/(\r\n)/gm, "\n");
webui.showError(trimmedData);
if (errorCallback) {
errorCallback(data.replace(/(\r\n)/gm, "\n"));
} else {
var trimmedData = data.replace(/(\r\n)/gm, "\n");
webui.showError(trimmedData);
}
},
});
}
Expand Down Expand Up @@ -3005,20 +3014,28 @@ webui.NewChangedFilesView = function(workspaceView) {

self.stash = function() {
var selectedFilesAsString = selectedItems.join(" ");
webui.git("add -- " + selectedFilesAsString, function(output) {
webui.git("add -- " + selectedFilesAsString, undefined, function(output) {
webui.git("stash push --include-untracked -- " + selectedFilesAsString, function(output) {
webui.showSuccess(output);
workspaceView.update();
});
},function(output) {
if (output.includes("did not match any files")) {
webui.showError("Stashing deleted items does not work. Please discard the operation instead.")
} else {
webui.showError(output);
}
});
}

self.discard = function() {
webui.git_command(["add", "--"].concat(selectedItems), function() {
function restoreCommand(data) {
webui.git_command(["restore", "--staged", "--worktree", "--"].concat(selectedItems), function() {
workspaceView.update();
});
});
}
// We want to try to run restore even if add fails (since the file might have already been added)
webui.git_command(["add", "--"].concat(selectedItems), restoreCommand,undefined,restoreCommand);
}

self.amend = function(message, details) {
Expand Down
35 changes: 26 additions & 9 deletions git-webui/src/share/git-webui/webui/js/git-webui.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ webui.parseGitResponse = function(data) {
};
}

webui.processGitResponse = function(data, command, callback, warningCallback) {
webui.processGitResponse = function(data, command, callback, warningCallback,errorCallback) {
var result = webui.parseGitResponse(data);
var rcode = result.rcode;
var output = result.output;
Expand Down Expand Up @@ -177,15 +177,20 @@ webui.processGitResponse = function(data, command, callback, warningCallback) {
location.reload();
return false;
}
webui.showError(displayMessage);
if (errorCallback) {
errorCallback(displayMessage);
} else {
webui.showError(displayMessage);
}

//}
} else {
webui.showError("The command <pre>"+command.join(" ")+"</pre> failed because of an unknown reason. Returned response: \n\n"+data)
}
}
}

webui.git_command = function(command, callback, warningCallback) {
webui.git_command = function(command, callback, warningCallback, errorCallback) {
$.ajax({
url: "git-command",
type: "POST",
Expand All @@ -194,11 +199,15 @@ webui.git_command = function(command, callback, warningCallback) {
command: command
}),
success: function(data) {
webui.processGitResponse(data, command, callback, warningCallback);
webui.processGitResponse(data, command, callback, warningCallback, errorCallback);
},
error: function(data) {
var trimmedData = data.replace(/(\r\n)/gm, "\n");
webui.showError(trimmedData);
if (errorCallback) {
errorCallback(data.replace(/(\r\n)/gm, "\n"));
} else {
var trimmedData = data.replace(/(\r\n)/gm, "\n");
webui.showError(trimmedData);
}
},
});
}
Expand Down Expand Up @@ -3005,20 +3014,28 @@ webui.NewChangedFilesView = function(workspaceView) {

self.stash = function() {
var selectedFilesAsString = selectedItems.join(" ");
webui.git("add -- " + selectedFilesAsString, function(output) {
webui.git("add -- " + selectedFilesAsString, undefined, function(output) {
webui.git("stash push --include-untracked -- " + selectedFilesAsString, function(output) {
webui.showSuccess(output);
workspaceView.update();
});
},function(output) {
if (output.includes("did not match any files")) {
webui.showError("Stashing deleted items does not work. Please discard the operation instead.")
} else {
webui.showError(output);
}
});
}

self.discard = function() {
webui.git_command(["add", "--"].concat(selectedItems), function() {
function restoreCommand(data) {
webui.git_command(["restore", "--staged", "--worktree", "--"].concat(selectedItems), function() {
workspaceView.update();
});
});
}
// We want to try to run restore even if add fails (since the file might have already been added)
webui.git_command(["add", "--"].concat(selectedItems), restoreCommand,undefined,restoreCommand);
}

self.amend = function(message, details) {
Expand Down
Loading