def remote_callback(): if not self.model.remotename: errmsg = self.tr('No repository selected.') qtutils.log(1, errmsg) return remote, kwargs = self.common_args() action = self.action # Check if we're about to create a new branch and warn. if action == 'push' and not self.model.remote_branch: branch = self.model.local_branch candidate = '%s/%s' % (remote, branch) if candidate not in self.model.remote_branches: msg = ('Branch "' + branch + '" does not exist in ' + remote + '.\n\nCreate a new branch?') if not qtutils.question(self.view, 'Create New Branch?', msg, default=False): return if not self.model.ffwd_only_checkbox: if action == 'fetch': msg = ('Non-fast-forward fetch overwrites local ' 'history!\n\tContinue?') elif action == 'push': msg = ('Non-fast-forward push overwrites published ' 'history!\nAre you sure you want to do this? ' '(Did you pull first?)\n\tContinue?') else: # pull: shouldn't happen since the controls are hidden msg = "You probably don't want to do this.\n\tContinue?" if not qtutils.question(self.view, 'Force %s?' % action.title(), msg, default=False): return # Disable the GUI by default self.view.setEnabled(False) self.progress.setEnabled(True) QtGui.QApplication.setOverrideCursor(Qt.WaitCursor) # Show a nice progress bar self.progress.setLabelText('Updating...') self.progress.show() # Use a thread to update in the background task = ActionTask(self.view, modelaction, remote, kwargs) self._tasks.append(task) QtCore.QThreadPool.globalInstance().start(task)
def abort_merge(): """Prompts before aborting a merge in progress """ txt = ('Abort merge?\n' 'Aborting the current merge will cause ' '*ALL* uncommitted changes to be lost.\n\n' 'Continue with aborting the current merge?') parent = QtGui.QApplication.instance().activeWindow() answer = qtutils.question(parent, 'Abort Merge?', txt, default=False) if answer: gitcmds.abort_merge()
def undo_selection(self): """Destructively check out content for the selected file from $head.""" if not qtutils.question(self, 'Destroy Local Changes?', 'This operation will drop ' 'uncommitted changes.\n' 'Continue?', default=False): return self.process_diff_selection(staged=False, apply_to_worktree=True, reverse=True, selected=True)
def undo_hunk(self): """Destructively remove a hunk from a worktree file.""" if not qtutils.question(self, 'Destroy Local Changes?', 'This operation will drop ' 'uncommitted changes.\n' 'Continue?', default=False): return self.process_diff_selection(staged=False, apply_to_worktree=True, reverse=True)
def stash_clear(self): """Clears all stashes """ if not qtutils.question(self.view, 'Drop All Stashes?', 'This will permanently remove ' 'ALL stashed changes.\n' 'Recovering these changes may not ' 'be possible.\n\n' 'Continue?'): return self.model.git.stash('clear'), self.update_model()
def remote_callback(): if not self.model.remotename: errmsg = self.tr('No repository selected.') qtutils.log(1, errmsg) return remote, kwargs = self.common_args() action = self.action # Check if we're about to create a new branch and warn. if action == 'push' and not self.model.remote_branch: branch = self.model.local_branch candidate = '%s/%s' % (remote, branch) if candidate not in self.model.remote_branches: msg = ('Branch "' + branch + '" does not exist in ' + remote + '.\n\nCreate a new branch?') if not qtutils.question(self.view, 'Create New Branch?', msg, default=False): return if not self.model.ffwd_only_checkbox: if action == 'fetch': msg = ('Non-fast-forward fetch overwrites local ' 'history!\n\tContinue?') elif action == 'push': msg = ('Non-fast-forward push overwrites published ' 'history!\nAre you sure you want to do this? ' '(Did you pull first?)\n\tContinue?') else: # pull: shouldn't happen since the controls are hidden msg = "You probably don't want to do this.\n\tContinue?" if not qtutils.question(self.view, 'Force %s?' % action.title(), msg, default=False): return status, output = modelaction(remote, **kwargs) if not output: # git fetch --tags --verbose doesn't print anything... output = self.tr('Already up-to-date.') # Force the status to 1 so that we always display the log qtutils.log(1, output) self.view.accept()
def commit(self): """Attempt to create a commit from the index and commit message.""" msg = unicode(self.commitmsg.toPlainText()) if not msg: # Describe a good commit message error_msg = self.tr('' 'Please supply a commit message.\n\n' 'A good commit message has the following format:\n\n' '- First line: Describe in one sentence what you did.\n' '- Second line: Blank\n' '- Remaining lines: Describe why this change is good.\n') qtutils.log(1, error_msg) cola.notifier().broadcast(signals.information, 'Missing Commit Message', error_msg) return if not self.model.staged: error_msg = self.tr('' 'No changes to commit.\n\n' 'You must stage at least 1 file before you can commit.') if self.model.modified: informative_text = self.tr('Would you like to stage ' 'and commit all modified files?') if not qtutils.confirm(self, 'Stage and commit?', error_msg, informative_text, ok_text='Stage and Commit'): return else: cola.notifier().broadcast(signals.information, 'Nothing to commit', error_msg) return cola.notifier().broadcast(signals.stage_modified) # Warn that amending published commits is generally bad amend = self.amend_checkbox.isChecked() if (amend and self.model.is_commit_published() and not qtutils.question(self, 'Rewrite Published Commit?', 'This commit has already been published.\n' 'You are rewriting published history.\n' 'You probably don\'t want to do this.\n\n' 'Continue?', default=False)): return # Perform the commit cola.notifier().broadcast(signals.commit, amend, msg)
def _remove_uncommitted_edits(self): if not self.model.undoable(): return items_to_undo = self.modified() if items_to_undo: if not qtutils.question( self, "Remove Uncommitted edits?", "This operation removes " "uncommitted edits.\n" "There's no going back. Continue?", default=False, ): return cola.notifier().broadcast(signals.checkout, ["HEAD", "--"] + items_to_undo) else: qtutils.log(1, self.tr("No files selected for " "checkout from HEAD."))
def _remove_uncommitted_edits(self): if not self.model.undoable(): return items_to_undo = self.modified() if items_to_undo: if not qtutils.question(self, 'Remove Uncommitted edits?', 'This operation removes ' 'uncommitted edits.\n' 'There\'s no going back. Continue?', default=False): return cola.notifier().broadcast(signals.checkout, ['HEAD', '--'] + items_to_undo) else: qtutils.log(1, self.tr('No files selected for ' 'checkout from HEAD.'))
def stash_drop(self): """Drops the currently selected stash """ selection = self.selected_stash() if not selection: return if not qtutils.question(self.view, 'Drop Stash?', 'This will permanently remove the ' 'selected stash.\n' 'Recovering these changes may not ' 'be possible.\n\n' 'Continue?'): return qtutils.log(*self.model.git.stash('drop', selection, with_stderr=True, with_status=True)) self.update_model()
def create_tag(self): """Verifies inputs and emits a notifier tag message.""" if not self.model.tag_name: cola.notifier().broadcast(signals.information, self.tr('Missing Name'), self.tr('You must name the tag.')) return if (self.model.sign_tag and not self.model.tag_msg and not qtutils.question(self.view, 'Use Empty Message?', 'Signing is enabled and the tag ' 'message is empty.\n\n' 'Continue?')): return cola.notifier().broadcast(signals.tag, self.model.tag_name, self.model.revision_item, sign=self.model.sign_tag, message=self.model.tag_msg) self.view.accept()
def stash_save(self): """Saves the worktree in a stash This prompts the user for a stash name and creates a git stash named accordingly. """ if not qtutils.question(self.view, 'Stash Changes?', 'This will stash your current ' 'changes away for later use.\n' 'Continue?'): return stash_name, ok = qtutils.prompt('Enter a name for this stash') if not ok: return while stash_name in self.model.stash_list: qtutils.information('Oops!', 'That name already exists. ' 'Please enter another name.') stash_name, ok = qtutils.prompt('Enter a name for this stash') if not ok: return if not stash_name: return # Sanitize the stash name stash_name = utils.sanitize(stash_name) args = [] if self.model.keep_index: args.append('--keep-index') args.append(stash_name) qtutils.log(*self.model.git.stash('save', with_stderr=True, with_status=True, *args)) self.view.accept()
def create_branch(self): """Creates a branch; called by the "Create Branch" button""" revision = self.model.revision branch = self.model.local_branch existing_branches = self.model.local_branches if not branch or not revision: qtutils.information('Missing Data', 'Please provide both a branch ' 'name and revision expression.') return check_branch = False if branch in existing_branches: if self.view.no_update_radio.isChecked(): msg = self.tr("Branch '%s' already exists.") msg = unicode(msg) % branch qtutils.information('warning', msg) return # Whether we should prompt the user for lost commits commits = gitcmds.rev_list_range(revision, branch) check_branch = bool(commits) if check_branch: msg = self.tr("Resetting '%s' to '%s' will " "lose the following commits:") lines = [ unicode(msg) % (branch, revision) ] for idx, commit in enumerate(commits): subject = commit[1][0:min(len(commit[1]),16)] if len(subject) < len(commit[1]): subject += '...' lines.append('\t' + commit[0][:8] +'\t' + subject) if idx >= 5: skip = len(commits) - 5 lines.append('\t(%d skipped)' % skip) break lines.extend([ unicode(self.tr('Recovering lost commits may not be easy.')), unicode(self.tr("Reset '%s'?")) % branch ]) result = qtutils.question(self.view, 'warning', '\n'.join(lines)) if not result: return # TODO handle fetch track = self.view.remote_radio.isChecked() fetch = self.view.fetch_checkbox.isChecked() ffwd = self.view.ffwd_only_radio.isChecked() reset = self.view.reset_radio.isChecked() chkout = self.view.checkout_checkbox.isChecked() status, output = self.model.create_branch(branch, revision, track=track) qtutils.log(status, output) if status == 0 and chkout: status, output = self.model.git.checkout(branch, with_status=True, with_stderr=True) qtutils.log(status, output) self.view.accept()
def _question(self, title, msg): return qtutils.question(self.parent, title, msg)