Files
nemo-repo-git-menu/nemoRepoGitMenu.py
T
dualfroz 1d80aa8879 refactor: rebuild as a git menu plugin on nemo-repo-core
Keeps the git half of the context menu from the single file extension. Open Terminal Here and Open in Editor are not git actions and work on any folder, so they moved to nemo-folder-tools.

The actions are a table rather than three near identical blocks, which is what makes adding git fetch a one line change. Entries now also appear inside a repository rather than only on its root, using the upward walk from nemo-repo-core.
2026-08-05 20:07:13 +02:00

97 lines
3.1 KiB
Python

#!/usr/bin/python3
"""nemo-repo-git-menu: git commands in Nemo's right click menu.
Entries appear on a folder that is inside a git repository, on the folder
itself and on the empty background of an open folder. Each one opens a
terminal in the repository root, runs the command and leaves the shell open
so the output stays readable.
Requires nemo-repo-core: https://github.com/dualfroz/nemo-repo-core
"""
import importlib.util
import os
import sys
def _ensureCoreOnPath():
if importlib.util.find_spec("nemoRepoCore") is not None:
return
dataHome = os.environ.get("XDG_DATA_HOME") or os.path.expanduser("~/.local/share")
dataDirs = (os.environ.get("XDG_DATA_DIRS") or "/usr/local/share:/usr/share").split(":")
for base in [dataHome] + dataDirs:
candidate = os.path.join(base, "nemo-repo-core")
if os.path.isdir(os.path.join(candidate, "nemoRepoCore")):
sys.path.insert(0, candidate)
return
_ensureCoreOnPath()
import gi
gi.require_version("Nemo", "3.0")
from gi.repository import GObject, Nemo
from nemoRepoCore import (coreConfig, findEnclosingRepoRoot, gitBinary,
launchTerminal, localDirectoryPath, requireCore)
requireCore("1.0.0")
pluginDefaults = {
"actions": {
"git_status": True,
"git_log": True,
"git_fetch": True,
"git_pull": True,
},
}
coreConfig.registerDefaults(pluginDefaults)
gitActions = [
("git_status", "Git Status", "git status",
"Show the working tree status in a terminal"),
("git_log", "Git Log", "git log --oneline --graph --decorate -30",
"Show the last 30 commits as a graph in a terminal"),
("git_fetch", "Git Fetch", "git fetch --all --prune",
"Fetch every remote and prune deleted branches"),
("git_pull", "Git Pull", "git pull",
"Pull the current branch from its upstream"),
]
def _menuItem(key, label, command, tip, repoRoot):
item = Nemo.MenuItem(name="NemoRepoGitMenu::%s" % key,
label="%s (terminal)" % label,
tip="%s, in %s" % (tip, repoRoot))
item.connect("activate", lambda *arguments: launchTerminal(repoRoot, command))
return item
class RepoGitMenuProvider(GObject.GObject, Nemo.MenuProvider,
Nemo.NameAndDescProvider):
def _itemsFor(self, path):
if not gitBinary:
return []
repoRoot = findEnclosingRepoRoot(path)
if repoRoot is None:
return []
return [_menuItem(key, label, command, tip, repoRoot)
for key, label, command, tip in gitActions
if coreConfig.sectionFlag("actions", key, True)]
def get_file_items(self, window, files):
if len(files) != 1:
return []
path = localDirectoryPath(files[0])
return self._itemsFor(path) if path else []
def get_background_items(self, window, currentFolder):
path = localDirectoryPath(currentFolder)
return self._itemsFor(path) if path else []
def get_name_and_desc(self):
return ["nemo-repo-git-menu:::Right click git actions (status, log, fetch, pull)"]