From 7b6393570fb7385ce95a042102502ef8d8144aee Mon Sep 17 00:00:00 2001 From: Johannes Gilger Date: Fri, 29 May 2009 14:08:35 +0200 Subject: [PATCH] PBWebChanges: Allow discarding of hunks This enables a "discard" button for unstaged hunks which simply gets rid of the changes (by using "git apply --reverse"). To avoid repetition, the stageHunk method was split into a more generic processHunk method. The "discard" functionality is called through discardHunk. The NSAlert shown when discarding can be bypassed by pressing "Alt" while clicking the discard-button. Signed-off-by: Johannes Gilger --- PBGitCommitController.h | 1 + PBGitCommitController.m | 16 +++++++++++++- PBWebChangesController.m | 17 ++++++++++++++ html/views/commit/commit.css | 5 +++-- html/views/commit/commit.js | 43 +++++++++++++++++++++++++++++++----- 5 files changed, 73 insertions(+), 9 deletions(-) diff --git a/PBGitCommitController.h b/PBGitCommitController.h index a099368..1126b07 100644 --- a/PBGitCommitController.h +++ b/PBGitCommitController.h @@ -42,6 +42,7 @@ - (void) readOtherFiles:(NSNotification *)notification; - (void) readUnstagedFiles:(NSNotification *)notification; - (void) stageHunk: (NSString *)hunk reverse:(BOOL)reverse; +- (void)discardHunk:(NSString *)hunk; - (NSString *)parentTree; diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 6cf8069..8a276d3 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -17,6 +17,7 @@ - (void) doneProcessingIndex; - (NSMutableDictionary *)dictionaryForLines:(NSArray *)lines; - (void) addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)staged tracked:(BOOL)tracked; +- (void)processHunk:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; @end @implementation PBGitCommitController @@ -366,7 +367,19 @@ - (void) stageHunk:(NSString *)hunk reverse:(BOOL)reverse { - NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apply", @"--cached", nil]; + [self processHunk:hunk stage:TRUE reverse:reverse]; +} + +- (void)discardHunk:(NSString *)hunk +{ + [self processHunk:hunk stage:FALSE reverse:TRUE]; +} + +- (void)processHunk:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse +{ + NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apply", nil]; + if (stage) + [array addObject:@"--cached"]; if (reverse) [array addObject:@"--reverse"]; @@ -382,4 +395,5 @@ // TODO: We should do this smarter by checking if the file diff is empty, which is faster. [self refresh:self]; } + @end diff --git a/PBWebChangesController.m b/PBWebChangesController.m index 1e2dd0d..f2838a3 100644 --- a/PBWebChangesController.m +++ b/PBWebChangesController.m @@ -87,6 +87,23 @@ [self refresh]; } +- (void)discardHunk:(NSString *)hunk altKey:(BOOL)altKey +{ + int ret = NSAlertDefaultReturn; + if (!altKey) { + ret = [[NSAlert alertWithMessageText:@"Discard hunk" + defaultButton:nil + alternateButton:@"Cancel" + otherButton:nil + informativeTextWithFormat:@"Are you sure you wish to discard the changes in this hunk?\n\n You cannot undo this operation."] runModal]; + } + + if (ret == NSAlertDefaultReturn) { + [controller discardHunk:hunk]; + [self refresh]; + } +} + - (void) setStateMessage:(NSString *)state { id script = [view windowScriptObject]; diff --git a/html/views/commit/commit.css b/html/views/commit/commit.css index 268109d..6d537dd 100644 --- a/html/views/commit/commit.css +++ b/html/views/commit/commit.css @@ -60,11 +60,12 @@ table.diff { float: right; } -.diff a.stagebutton { +.diff a.hunkbutton { width: 40px; padding: 0 2px 0 2px; margin-bottom: 4px; - margin-right: 10px; + margin-right: 1px; + float: right; border: 1px solid #3465a4; background-color: #cce5ff; diff --git a/html/views/commit/commit.js b/html/views/commit/commit.js index 4143540..a120e04 100644 --- a/html/views/commit/commit.js +++ b/html/views/commit/commit.js @@ -87,15 +87,28 @@ var displayDiff = function(diff, cached) for (i = 0; i < hunkHeaders.length; ++i) { var header = hunkHeaders[i]; if (cached) - header.innerHTML = "Unstage" + header.innerHTML; - else - header.innerHTML = "Stage" + header.innerHTML; + header.innerHTML = "Unstage" + header.innerHTML; + else { + header.innerHTML = "Stage" + header.innerHTML; + header.innerHTML = "Discard" + header.innerHTML; + } } } -var addHunk = function(hunk, reverse) +var getNextText = function(element) { - hunkHeader = hunk.nextSibling.data.split("\n")[0]; + // gets the next DOM sibling which has type "text" (e.g. our hunk-header) + next = element; + while (next.nodeType != 3) { + next = next.nextSibling; + } + return next; +} + +var getHunkText = function(hunk) +{ + hunk = getNextText(hunk); + hunkHeader = hunk.data.split("\n")[0]; if (m = hunkHeader.match(/@@.*@@/)) hunkHeader = m; @@ -108,11 +121,29 @@ var addHunk = function(hunk, reverse) if (end == -1) end = originalDiff.length; - hunkText = originalDiff.substring(start, end); + var hunkText = originalDiff.substring(start, end); hunkText = diffHeader + "\n" + hunkText + "\n"; + return hunkText; +} + +var addHunk = function(hunk, reverse) +{ + var hunkText = getHunkText(hunk); + if (Controller.stageHunk_reverse_) Controller.stageHunk_reverse_(hunkText, reverse); else alert(hunkText); } + +var discardHunk = function(hunk, event) +{ + var hunkText = getHunkText(hunk); + + if (Controller.discardHunk_altKey_) { + Controller.discardHunk_altKey_(hunkText, event.altKey == true); + } else { + alert(hunkText); + } +}