|
6 | 6 | // Copyright 2008 __MyCompanyName__. All rights reserved.
|
7 | 7 | //
|
8 | 8 |
|
| 9 | +#import <Quartz/Quartz.h> |
| 10 | + |
9 | 11 | #import "PBGitCommit.h"
|
10 | 12 | #import "PBGitTree.h"
|
11 | 13 | #import "PBGitRef.h"
|
|
30 | 32 | #import "GLFileView.h"
|
31 | 33 | #import "GitXCommitCopier.h"
|
32 | 34 | #import "NSSplitView+GitX.h"
|
33 |
| -#import <Quartz/Quartz.h> |
34 |
| - |
| 35 | +#import "PBRefMenuItem.h" |
| 36 | +#import "PBGitStash.h" |
35 | 37 |
|
36 | 38 | #define kHistorySelectedDetailIndexKey @"PBHistorySelectedDetailIndex"
|
37 | 39 | #define kHistoryDetailViewIndex 0
|
@@ -559,7 +561,13 @@ - (void) checkoutFiles:(id)sender
|
559 | 561 | NSMutableArray *files = [NSMutableArray array];
|
560 | 562 | for (NSString *filePath in [sender representedObject])
|
561 | 563 | [files addObject:[filePath stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
|
562 |
| - [repository checkoutFiles:files fromRefish:self.selectedCommits.firstObject]; |
| 564 | + |
| 565 | + NSError *error = nil; |
| 566 | + BOOL success = [repository checkoutFiles:files fromRefish:self.selectedCommits.firstObject error:&error]; |
| 567 | + if (!success) { |
| 568 | + [self.windowController showErrorSheet:error]; |
| 569 | + } |
| 570 | + |
563 | 571 | }
|
564 | 572 |
|
565 | 573 | - (void) diffFilesAction:(id)sender
|
@@ -632,45 +640,266 @@ - (NSArray *)menuItemsForPaths:(NSArray *)paths
|
632 | 640 |
|
633 | 641 | #pragma mark Repository Methods
|
634 | 642 |
|
635 |
| -- (IBAction) createBranch:(id)sender |
| 643 | +- (id <PBGitRefish>)refishForSender:(id)sender |
636 | 644 | {
|
637 |
| - PBGitRef *currentRef = [repository.currentBranch ref]; |
638 |
| - |
639 |
| - PBGitCommit *selectedCommit = self.selectedCommits.firstObject; |
640 |
| - if (!selectedCommits.firstObject || [selectedCommit hasRef:currentRef]) |
641 |
| - [PBCreateBranchSheet beginSheetWithRefish:currentRef windowController:self.windowController]; |
642 |
| - else |
643 |
| - [PBCreateBranchSheet beginSheetWithRefish:selectedCommit windowController:self.windowController]; |
| 645 | + return [self refishForSender:sender refishTypes:nil]; |
644 | 646 | }
|
645 | 647 |
|
646 |
| -- (IBAction) createTag:(id)sender |
| 648 | +- (id <PBGitRefish>)refishForSender:(id)sender refishTypes:(NSArray *)types |
647 | 649 | {
|
648 |
| - PBGitCommit *selectedCommit = self.selectedCommits.firstObject; |
649 |
| - if (!selectedCommit) |
650 |
| - [PBCreateTagSheet beginSheetWithRefish:[repository.currentBranch ref] windowController:self.windowController]; |
651 |
| - else |
652 |
| - [PBCreateTagSheet beginSheetWithRefish:selectedCommit windowController:self.windowController]; |
| 650 | + if ([sender isKindOfClass:[PBRefMenuItem class]]) { |
| 651 | + id <PBGitRefish> refish = [[(PBRefMenuItem *)sender refishs] firstObject]; |
| 652 | + |
| 653 | + if (!types || [types indexOfObject:[refish refishType]] != NSNotFound) |
| 654 | + return refish; |
| 655 | + return nil; |
| 656 | + } |
| 657 | + |
| 658 | + if ([types indexOfObject:kGitXCommitType] == NSNotFound) |
| 659 | + return nil; |
| 660 | + |
| 661 | + return self.selectedCommits.firstObject; |
| 662 | +} |
| 663 | + |
| 664 | +- (IBAction)fetchRemote:(id)sender |
| 665 | +{ |
| 666 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType]]; |
| 667 | + if (!refish) |
| 668 | + return; |
| 669 | + |
| 670 | + [self.windowController performFetchForRef:refish]; |
| 671 | +} |
| 672 | + |
| 673 | +- (IBAction)pullRemote:(id)sender |
| 674 | +{ |
| 675 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType]]; |
| 676 | + if (!refish) |
| 677 | + return; |
| 678 | + |
| 679 | + [self.windowController performPullForBranch:refish remote:nil rebase:NO]; |
| 680 | +} |
| 681 | + |
| 682 | +- (IBAction)pushUpdatesToRemote:(id)sender |
| 683 | +{ |
| 684 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType]]; |
| 685 | + if (!refish) |
| 686 | + return; |
| 687 | + |
| 688 | + PBGitRef *remoteRef = nil; // [(PBGitRef *)sender.refishs.firstObject remoteRef]; |
| 689 | + |
| 690 | + [self.windowController performPushForBranch:nil toRemote:remoteRef]; |
| 691 | +} |
| 692 | + |
| 693 | +- (IBAction)pushDefaultRemoteForRef:(id)sender |
| 694 | +{ |
| 695 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType]]; |
| 696 | + if (!refish) |
| 697 | + return; |
| 698 | + |
| 699 | + PBGitRef *ref = nil; |
| 700 | + |
| 701 | + [self.windowController performPushForBranch:ref toRemote:nil]; |
| 702 | +} |
| 703 | + |
| 704 | +- (IBAction)pushToRemote:(id)sender |
| 705 | +{ |
| 706 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType]]; |
| 707 | + if (!refish) |
| 708 | + return; |
| 709 | + |
| 710 | + PBGitRef *ref = nil; |
| 711 | + NSString *remoteName = [sender representedObject]; |
| 712 | + PBGitRef *remoteRef = [PBGitRef refFromString:[kGitXRemoteRefPrefix stringByAppendingString:remoteName]]; |
| 713 | + |
| 714 | + [self.windowController performPushForBranch:ref toRemote:remoteRef]; |
| 715 | +} |
| 716 | + |
| 717 | +- (IBAction)merge:(id)sender |
| 718 | +{ |
| 719 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType, kGitXCommitType, kGitXTagType]]; |
| 720 | + if (!refish) return; |
| 721 | + |
| 722 | + NSError *error = nil; |
| 723 | + BOOL success = [repository mergeWithRefish:refish error:&error]; |
| 724 | + if (!success) { |
| 725 | + [self.windowController showErrorSheet:error]; |
| 726 | + } |
| 727 | +} |
| 728 | + |
| 729 | +- (IBAction)checkout:(id)sender |
| 730 | +{ |
| 731 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType, kGitXCommitType, kGitXTagType]]; |
| 732 | + if (!selectedCommits) return; |
| 733 | + |
| 734 | + NSError *error = nil; |
| 735 | + BOOL success = [repository checkoutRefish:refish error:&error]; |
| 736 | + if (!success) { |
| 737 | + [self.windowController showErrorSheet:error]; |
| 738 | + } |
| 739 | +} |
| 740 | + |
| 741 | +- (IBAction)cherryPick:(id)sender |
| 742 | +{ |
| 743 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXCommitType]]; |
| 744 | + if (!refish) return; |
| 745 | + |
| 746 | + NSError *error = nil; |
| 747 | + BOOL success = [repository cherryPickRefish:refish error:&error]; |
| 748 | + if (!success) { |
| 749 | + [self.windowController showErrorSheet:error]; |
| 750 | + } |
| 751 | +} |
| 752 | + |
| 753 | +- (IBAction)rebase:(id)sender |
| 754 | +{ |
| 755 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType]]; |
| 756 | + if (!refish) return; |
| 757 | + |
| 758 | + NSError *error = nil; |
| 759 | + BOOL success = [repository rebaseBranch:nil onRefish:refish error:&error]; |
| 760 | + if (!success) { |
| 761 | + [self.windowController showErrorSheet:error]; |
| 762 | + } |
| 763 | +} |
| 764 | + |
| 765 | +- (IBAction) rebaseHeadBranch:(id)sender |
| 766 | +{ |
| 767 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType]]; |
| 768 | + NSError *error = nil; |
| 769 | + BOOL success = [self.repository rebaseBranch:nil onRefish:refish error:&error]; |
| 770 | + if (!success) { |
| 771 | + [self.windowController showErrorSheet:error]; |
| 772 | + } |
| 773 | +} |
| 774 | + |
| 775 | +- (IBAction)showDeleteRefSheet:(PBRefMenuItem *)sender |
| 776 | +{ |
| 777 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXBranchType]]; |
| 778 | + if (!refish) |
| 779 | + return; |
| 780 | + |
| 781 | + PBGitRef *ref = (PBGitRef *)refish; |
| 782 | + |
| 783 | + void (^performDelete)(void) = ^{ |
| 784 | + NSError *error = nil; |
| 785 | + BOOL success = [self.repository deleteRef:ref error:&error]; |
| 786 | + if (!success) { |
| 787 | + [self.windowController showErrorSheet:error]; |
| 788 | + } |
| 789 | + return; |
| 790 | + }; |
| 791 | + |
| 792 | + if ([PBGitDefaults isDialogWarningSuppressedForDialog:kDialogDeleteRef]) { |
| 793 | + performDelete(); |
| 794 | + return; |
| 795 | + } |
| 796 | + |
| 797 | + NSString *ref_desc = [NSString stringWithFormat:@"%@ '%@'", [ref refishType], [ref shortName]]; |
| 798 | + |
| 799 | + NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:@"Delete %@?", ref_desc] |
| 800 | + defaultButton:@"Delete" |
| 801 | + alternateButton:@"Cancel" |
| 802 | + otherButton:nil |
| 803 | + informativeTextWithFormat:@"Are you sure you want to remove the %@?", ref_desc]; |
| 804 | + [alert setShowsSuppressionButton:YES]; |
| 805 | + |
| 806 | + [alert beginSheetModalForWindow:self.windowController.window |
| 807 | + completionHandler:^(NSModalResponse returnCode) { |
| 808 | + if ([[alert suppressionButton] state] == NSOnState) |
| 809 | + [PBGitDefaults suppressDialogWarningForDialog:kDialogDeleteRef]; |
| 810 | + |
| 811 | + if (returnCode == NSModalResponseOK) { |
| 812 | + performDelete(); |
| 813 | + } |
| 814 | + }]; |
| 815 | +} |
| 816 | + |
| 817 | +- (IBAction)diffWithHEAD:(id)sender |
| 818 | +{ |
| 819 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:nil]; |
| 820 | + if (!refish) |
| 821 | + return; |
| 822 | + |
| 823 | + PBGitCommit *commit = [self.repository commitForRef:refish]; |
| 824 | + |
| 825 | + NSString *diff = [self.repository performDiff:commit against:nil forFiles:nil]; |
| 826 | + |
| 827 | + [PBDiffWindowController showDiff:diff]; |
653 | 828 | }
|
654 | 829 |
|
655 |
| -- (IBAction) merge:(id)sender |
| 830 | +- (IBAction)stashPop:(id)sender |
656 | 831 | {
|
657 |
| - PBGitCommit *selectedCommit = self.selectedCommits.firstObject; |
658 |
| - if (selectedCommit) |
659 |
| - [repository mergeWithRefish:selectedCommit]; |
| 832 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXStashType]]; |
| 833 | + PBGitStash *stash = [self.repository stashForRef:refish]; |
| 834 | + NSError *error = nil; |
| 835 | + BOOL success = [self.repository stashPop:stash error:&error]; |
| 836 | + |
| 837 | + if (!success) { |
| 838 | + [self.windowController showErrorSheet:error]; |
| 839 | + } else { |
| 840 | + [self.windowController showCommitView:sender]; |
| 841 | + } |
660 | 842 | }
|
661 | 843 |
|
662 |
| -- (IBAction) cherryPick:(id)sender |
| 844 | +- (IBAction)stashApply:(id)sender |
663 | 845 | {
|
664 |
| - PBGitCommit *selectedCommit = self.selectedCommits.firstObject; |
665 |
| - if (selectedCommit) |
666 |
| - [repository cherryPickRefish:selectedCommit]; |
| 846 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXStashType]]; |
| 847 | + PBGitStash *stash = [self.repository stashForRef:refish]; |
| 848 | + NSError *error = nil; |
| 849 | + BOOL success = [self.repository stashApply:stash error:&error]; |
| 850 | + |
| 851 | + if (!success) { |
| 852 | + [self.windowController showErrorSheet:error]; |
| 853 | + } else { |
| 854 | + [self.windowController showCommitView:sender]; |
| 855 | + } |
667 | 856 | }
|
668 | 857 |
|
669 |
| -- (IBAction) rebase:(id)sender |
| 858 | +- (IBAction)stashDrop:(id)sender |
670 | 859 | {
|
671 |
| - PBGitCommit *selectedCommit = self.selectedCommits.firstObject; |
672 |
| - if (selectedCommit) |
673 |
| - [repository rebaseBranch:nil onRefish:selectedCommit]; |
| 860 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXStashType]]; |
| 861 | + PBGitStash *stash = [self.repository stashForRef:refish]; |
| 862 | + NSError *error = nil; |
| 863 | + BOOL success = [self.repository stashDrop:stash error:&error]; |
| 864 | + |
| 865 | + if (!success) { |
| 866 | + [self.windowController showErrorSheet:error]; |
| 867 | + } else { |
| 868 | + [self.windowController showHistoryView:sender]; |
| 869 | + } |
| 870 | +} |
| 871 | + |
| 872 | +- (IBAction)stashViewDiff:(id)sender |
| 873 | +{ |
| 874 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXStashType]]; |
| 875 | + PBGitStash *stash = [self.repository stashForRef:refish]; |
| 876 | + [PBDiffWindowController showDiffWindowWithFiles:nil fromCommit:stash.ancestorCommit diffCommit:stash.commit]; |
| 877 | +} |
| 878 | + |
| 879 | +- (IBAction)showTagInfoSheet:(id)sender |
| 880 | +{ |
| 881 | + id <PBGitRefish> refish = [self refishForSender:sender refishTypes:@[kGitXTagType]]; |
| 882 | + if (!refish) |
| 883 | + return; |
| 884 | + |
| 885 | + PBGitRef *ref = (PBGitRef *)refish; |
| 886 | + |
| 887 | + NSError *error = nil; |
| 888 | + NSString *tagName = [ref tagName]; |
| 889 | + NSString *tagRef = [@"refs/tags/" stringByAppendingString:tagName]; |
| 890 | + GTObject *object = [self.repository.gtRepo lookUpObjectByRevParse:tagRef error:&error]; |
| 891 | + if (!object) { |
| 892 | + NSLog(@"Couldn't look up ref %@:%@", tagRef, [error debugDescription]); |
| 893 | + return; |
| 894 | + } |
| 895 | + NSString *title = [NSString stringWithFormat:@"Info for tag: %@", tagName]; |
| 896 | + NSString *info = @""; |
| 897 | + if ([object isKindOfClass:[GTTag class]]) { |
| 898 | + GTTag *tag = (GTTag*)object; |
| 899 | + info = tag.message; |
| 900 | + } |
| 901 | + |
| 902 | + [self.windowController showMessageSheet:title infoText:info]; |
674 | 903 | }
|
675 | 904 |
|
676 | 905 | #pragma mark -
|
|
0 commit comments