mirror of
https://github.com/Murmele/Gittyup.git
synced 2024-09-11 10:45:39 +03:00
Merge remote-tracking branch 'origin/master' into libgit2update
This commit is contained in:
commit
ebb739b3bb
61
.github/workflows/build.yml
vendored
61
.github/workflows/build.yml
vendored
@ -46,9 +46,7 @@ jobs:
|
||||
run: |
|
||||
pacman --noconfirm -Suy
|
||||
pacman --noconfirm -S flatpak flatpak-builder xorg-server-xvfb
|
||||
flatpak install --assumeyes org.kde.Sdk//5.15-21.08
|
||||
flatpak install --assumeyes org.freedesktop.Sdk.Extension.golang//21.08
|
||||
flatpak install --assumeyes org.kde.Platform//5.15-21.08
|
||||
flatpak install --assumeyes org.freedesktop.Sdk.Extension.golang//23.08
|
||||
|
||||
- name: Show environment variables
|
||||
run: >
|
||||
@ -67,57 +65,53 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Clone flatpak manifest from Flathub
|
||||
uses: GuillaumeFalourd/clone-github-repo-action@v2
|
||||
with:
|
||||
owner: 'flathub'
|
||||
repository: 'com.github.Murmele.Gittyup'
|
||||
|
||||
- name: Replace git tag by the commit id on which it runs
|
||||
if: github.ref_type != 'tag'
|
||||
run: >
|
||||
sed -i 's@tag: .*@commit: "${{ (github.event.pull_request && github.event.pull_request.head.sha) || github.sha }}"@' com.github.Murmele.Gittyup/com.github.Murmele.Gittyup.yml
|
||||
sed -i 's@tag: .*@commit: "${{ (github.event.pull_request && github.event.pull_request.head.sha) || github.sha }}"@' com.github.Murmele.Gittyup.yml
|
||||
|
||||
- name: Use correct git tag
|
||||
if: github.ref_type == 'tag'
|
||||
run: >
|
||||
sed -i 's@tag: .*$@tag: "${{ github.ref_name }}"@' com.github.Murmele.Gittyup/com.github.Murmele.Gittyup.yml
|
||||
sed -i 's@tag: .*$@tag: "${{ github.ref_name }}"@' com.github.Murmele.Gittyup.yml
|
||||
|
||||
- name: Replace source url
|
||||
run: >
|
||||
sed -i "s@url: .*Gittyup.git@url: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY@" com.github.Murmele.Gittyup/com.github.Murmele.Gittyup.yml
|
||||
sed -i "s@url: .*Gittyup.git@url: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY@" com.github.Murmele.Gittyup.yml
|
||||
|
||||
- name: Add dev build marker to cmake options
|
||||
if: github.ref_type != 'tag'
|
||||
run: >
|
||||
sed -i 's@config-opts: \["\(.*\)"\]@config-opts: ["\1", "-DDEV_BUILD=${{ github.ref_name }}"]@' com.github.Murmele.Gittyup/com.github.Murmele.Gittyup.yml
|
||||
sed -i 's@config-opts: \["\(.*\)"\]@config-opts: ["\1", "-DDEV_BUILD=${{ github.ref_name }}"]@' com.github.Murmele.Gittyup.yml
|
||||
|
||||
- name: Replace desktop file name suffix
|
||||
if: github.ref_type != 'tag'
|
||||
run: >
|
||||
sed -i 's@desktop-file-name-suffix: ""@desktop-file-name-suffix: " (Development)"@' com.github.Murmele.Gittyup/com.github.Murmele.Gittyup.yml
|
||||
sed -i 's@desktop-file-name-suffix: ""@desktop-file-name-suffix: " (Development)"@' com.github.Murmele.Gittyup.yml
|
||||
|
||||
- name: Enable automatic update
|
||||
if: github.ref_type != 'tag'
|
||||
run: >
|
||||
sed -i 's@-DENABLE_UPDATE_OVER_GUI=OFF@-DENABLE_UPDATE_OVER_GUI=ON@' com.github.Murmele.Gittyup/com.github.Murmele.Gittyup.yml
|
||||
sed -i 's@-DENABLE_UPDATE_OVER_GUI=OFF@-DENABLE_UPDATE_OVER_GUI=ON@' com.github.Murmele.Gittyup.yml
|
||||
|
||||
- name: Show Flatpak manifest
|
||||
run: cat com.github.Murmele.Gittyup/com.github.Murmele.Gittyup.yml
|
||||
run: cat com.github.Murmele.Gittyup.yml
|
||||
|
||||
- name: Build package
|
||||
uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4
|
||||
uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
bundle: Gittyup.flatpak
|
||||
manifest-path: com.github.Murmele.Gittyup/com.github.Murmele.Gittyup.yml
|
||||
manifest-path: com.github.Murmele.Gittyup.yml
|
||||
cache: false
|
||||
upload-artifact: true
|
||||
verbose: true
|
||||
branch: ${{ steps.flatpak_release_branch.outputs.value }}
|
||||
|
||||
- name: Publish build artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: com.github.Murmele.Gittyup/*
|
||||
name: Gittyup Flatpak
|
||||
path: Gittyup.flatpak
|
||||
name: GittyupFlatpak
|
||||
|
||||
|
||||
build:
|
||||
@ -145,7 +139,7 @@ jobs:
|
||||
cmake_env: {}
|
||||
|
||||
- name: macos
|
||||
os: macos-latest
|
||||
os: macos-12
|
||||
ninja_platform: mac
|
||||
qt_platform: mac
|
||||
openssl_arch: darwin64-x86_64-cc
|
||||
@ -230,9 +224,9 @@ jobs:
|
||||
modules: qtwebengine
|
||||
|
||||
- name: Install Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v3
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.9.0
|
||||
version: 1.11.1
|
||||
platform: ${{ matrix.env.ninja_platform }}
|
||||
destination: ninja
|
||||
|
||||
@ -388,17 +382,6 @@ jobs:
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
- name: list artifacts folder
|
||||
run: |
|
||||
echo "Show artifacts folder:"
|
||||
ls artifacts
|
||||
echo "Show artifacts/Gittyup Flatpak folder:"
|
||||
ls "artifacts/Gittyup Flatpak"
|
||||
echo "Show artifacts/Gittyup-x86_64:"
|
||||
ls "artifacts/Gittyup-x86_64"
|
||||
echo "Show artifacts/Gittyup VERSION"
|
||||
ls "artifacts/Gittyup-VERSION"
|
||||
|
||||
# version is exported from cmake to file
|
||||
- name: Retrieve version
|
||||
@ -417,9 +400,8 @@ jobs:
|
||||
**/artifacts/Gittyup win64/Gittyup*.exe
|
||||
**/artifacts/Gittyup win32/Gittyup*.exe
|
||||
**/artifacts/Gittyup macos/Gittyup*.dmg
|
||||
**/artifacts/Gittyup Flatpak/com.github.Murmele.Gittyup.yml
|
||||
**/Gittyup-x86_64/*.flatpak
|
||||
**/artifacts/GittyupAppImage/*
|
||||
**/artifacts/GittyupFlatpak/*.flatpak
|
||||
**/artifacts/GittyupAppImage/Gittyup*.AppImage
|
||||
|
||||
- name: Update GitHub release (version tag)
|
||||
uses: marvinpinto/action-automatic-releases@latest
|
||||
@ -433,9 +415,8 @@ jobs:
|
||||
**/artifacts/Gittyup win64/Gittyup*.exe
|
||||
**/artifacts/Gittyup win32/Gittyup*.exe
|
||||
**/artifacts/Gittyup macos/Gittyup*.dmg
|
||||
**/artifacts/Gittyup Flatpak/com.github.Murmele.Gittyup.yml
|
||||
**/Gittyup-x86_64/*.flatpak
|
||||
**/artifacts/GittyupAppImage/*
|
||||
**/artifacts/GittyupFlatpak/*.flatpak
|
||||
**/artifacts/GittyupAppImage/Gittyup*.AppImage
|
||||
|
||||
# needed otherwise the docs folder is not available
|
||||
- name: Checkout repository
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,4 +11,4 @@ build
|
||||
.idea/
|
||||
.venv
|
||||
compile_commands.json
|
||||
|
||||
tags
|
@ -6,7 +6,7 @@ set(GITTYUP_NAME "Gittyup")
|
||||
set(GITTYUP_EXECUTABLE_NAME "gittyup")
|
||||
set(GITTYUP_IDENTIFIER "com.github.Murmele.Gittyup")
|
||||
set(GITTYUP_VERSION_MAJOR 1)
|
||||
set(GITTYUP_VERSION_MINOR 3)
|
||||
set(GITTYUP_VERSION_MINOR 4)
|
||||
set(GITTYUP_VERSION_PATCH 0)
|
||||
set(GITTYUP_VERSION
|
||||
"${GITTYUP_VERSION_MAJOR}.${GITTYUP_VERSION_MINOR}.${GITTYUP_VERSION_PATCH}"
|
||||
|
@ -1,7 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Scientific Toolworks, Inc.
|
||||
Copyright (c) 2021-2023 Gittyup contributors
|
||||
Copyright (c) 2021-2024 Gittyup contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -92,7 +92,7 @@ How to Build
|
||||
**Initialize Submodules**
|
||||
|
||||
git submodule init
|
||||
git submodule update
|
||||
git submodule update --depth 1
|
||||
|
||||
**Build OpenSSL**
|
||||
|
||||
@ -194,7 +194,7 @@ branch. Create pull requests against the `master` branch. Follow the
|
||||
[seven guidelines](https://chris.beams.io/posts/git-commit/) to writing a
|
||||
great commit message.
|
||||
|
||||
Prior to committing a change, please use `cl-format.sh` to ensure your code
|
||||
Prior to committing a change, please use `cl-fmt.sh` to ensure your code
|
||||
adheres to the formatting conventions for this project. You can also use the
|
||||
`setup-env.sh` script to install a pre-commit hook which will automatically
|
||||
run `clang-format` against all modified files.
|
||||
|
75
com.github.Murmele.Gittyup.yml
Normal file
75
com.github.Murmele.Gittyup.yml
Normal file
@ -0,0 +1,75 @@
|
||||
app-id: com.github.Murmele.Gittyup
|
||||
runtime: org.kde.Platform
|
||||
runtime-version: 5.15-23.08
|
||||
sdk: org.kde.Sdk
|
||||
command: gittyup
|
||||
desktop-file-name-suffix: "" # used to create development version
|
||||
finish-args:
|
||||
- --socket=wayland
|
||||
- --socket=fallback-x11
|
||||
- --device=dri
|
||||
- --share=network
|
||||
- --share=ipc
|
||||
- --filesystem=home
|
||||
- --filesystem=/tmp # Needed to store temporary files, which should be opened by external (non sandboxed) applications like kdiff3. Did not find another way to share a temporary file to the host (only creating a tmp folder in the home folder, I don't like)
|
||||
# we use the keyring to store credentials
|
||||
- --filesystem=xdg-run/keyring
|
||||
# for git repos that require ssh keys
|
||||
- --socket=ssh-auth
|
||||
- --talk-name=org.freedesktop.secrets
|
||||
- --talk-name=org.freedesktop.Notifications
|
||||
- --talk-name=org.freedesktop.Flatpak
|
||||
rename-icon: gittyup # Image will renamed to match the app-id konvention
|
||||
rename-desktop-file: gittyup.desktop
|
||||
rename-appdata-file: gittyup.appdata.xml
|
||||
|
||||
build-options:
|
||||
append-path: /usr/lib/sdk/golang/bin
|
||||
|
||||
modules:
|
||||
- name: git-lfs
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- PREFIX=${FLATPAK_DEST} ./install.sh
|
||||
sources:
|
||||
- type: archive
|
||||
strip-components: 1
|
||||
url: https://github.com/git-lfs/git-lfs/releases/download/v3.5.1/git-lfs-linux-amd64-v3.5.1.tar.gz
|
||||
sha256: 6f28eb19faa7a968882dca190d92adc82493378b933958d67ceaeb9ebe4d731e
|
||||
only-arches: [x86_64]
|
||||
x-checker-data:
|
||||
type: json
|
||||
url: https://api.github.com/repos/git-lfs/git-lfs/releases/latest
|
||||
url-query: .assets[] | select(.name=="git-lfs-linux-amd64-" + $version +
|
||||
".tar.gz") | .browser_download_url
|
||||
version-query: .tag_name
|
||||
- type: archive
|
||||
strip-components: 1
|
||||
url: https://github.com/git-lfs/git-lfs/releases/download/v3.5.1/git-lfs-linux-arm64-v3.5.1.tar.gz
|
||||
sha256: 4f8700aacaa0fd26ae5300fb0996aed14d1fd0ce1a63eb690629c132ff5163a9
|
||||
only-arches: [aarch64]
|
||||
x-checker-data:
|
||||
type: json
|
||||
url: https://api.github.com/repos/git-lfs/git-lfs/releases/latest
|
||||
url-query: .assets[] | select(.name=="git-lfs-linux-arm64-" + $version +
|
||||
".tar.gz") | .browser_download_url
|
||||
version-query: .tag_name
|
||||
|
||||
- name: git
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- install -Dm755 $(which git) ${FLATPAK_DEST}/bin/
|
||||
- install -Dm755 $(which git-cvsserver) ${FLATPAK_DEST}/bin/
|
||||
- install -Dm755 $(which git-receive-pack) ${FLATPAK_DEST}/bin/
|
||||
- install -Dm755 $(which git-shell) ${FLATPAK_DEST}/bin/
|
||||
- install -Dm755 $(which git-upload-archive) ${FLATPAK_DEST}/bin/
|
||||
- install -Dm755 $(which git-upload-pack) ${FLATPAK_DEST}/bin/
|
||||
|
||||
- name: Gittyup
|
||||
buildsystem: cmake-ninja
|
||||
config-opts: [-DCMAKE_BUILD_TYPE=Release, -DFLATPAK=ON, -DGENERATE_APPDATA=ON, -DENABLE_UPDATE_OVER_GUI=OFF, -DUSE_SYSTEM_OPENSSL:BOOL=ON]
|
||||
builddir: true
|
||||
sources:
|
||||
- type: git
|
||||
url: https://github.com/Murmele/Gittyup.git
|
||||
tag: gittyup_v1.3.0
|
@ -14,6 +14,9 @@ return {
|
||||
family = family,
|
||||
size = size
|
||||
},
|
||||
view = {
|
||||
showWhitespace = false
|
||||
},
|
||||
indent = {
|
||||
tabs = true,
|
||||
width = 4,
|
||||
|
@ -1,4 +1,4 @@
|
||||
### vX.X.X - 2023-04-20 (DEV)
|
||||
### v1.4.0 - 2024-04-24 (DEV)
|
||||
|
||||
Description
|
||||
|
||||
@ -6,12 +6,28 @@ Description
|
||||
|
||||
* UI(Commit List): Added a right-click menu entry to rename branches.
|
||||
* UI(Main Menu): Added a menu-entry to rename the current branch.
|
||||
* UI(Diff View): Added line wrapping option in Tools - Options - Diff
|
||||
* Option to open Gittyup maximized at startup
|
||||
* Hotkeys for Navigating CommitList
|
||||
* Referring repos with their git-dir instead of their work-tree.
|
||||
* Use columns for file name, directory, and state when files are shown as a list in TreeViews.
|
||||
* Possibility to change language from the settings
|
||||
* Linux: Publishing Appimage bundle
|
||||
* Hide Untracked Files option to DoubleTreeWidget
|
||||
* Add display options to the commit list
|
||||
|
||||
#### Changed
|
||||
|
||||
* UI(Commit List): Collapse multiple branch and tag right-click menu entries
|
||||
into submenus. This affects the checkout and delete operations.
|
||||
* Fix(Build System): Force usage of clang-format v13 to ensure consistent formatting.
|
||||
* Fix: Commit highlighting
|
||||
* Compact commit list: move commit message closer to commit graph
|
||||
* Updating translations
|
||||
* Close the branch drop-down list after the user checks out a branch.
|
||||
* Fix: Delete timeline causes crash on windows
|
||||
* Fix: Rebase: Use original commit message as default message
|
||||
* Fix: Stage all button
|
||||
|
||||
----
|
||||
|
||||
|
@ -79,6 +79,11 @@ See blame of the current version with an integrated timeline to see who changed
|
||||
|
||||
![Blame View](https://raw.githubusercontent.com/Murmele/Gittyup/master/rsrc/screenshots/BlameView.png)
|
||||
|
||||
### Dynamic Line Wrapping
|
||||
Courtesy of Scintilla.
|
||||
|
||||
![Line Wrapping](/rsrc/screenshots/line-wrap-demo-2.gif)
|
||||
|
||||
### Single line staging
|
||||
by eighter clicking on the checkboxes next to each line or by selecting the relevant code and pressing "S". For unstaging you can uncheck the checkboxes or press "U". To revert changes, select the text and press "R".
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -46,7 +46,6 @@
|
||||
|
||||
<provides>
|
||||
<binary>gittyup</binary>
|
||||
<id>com.github.Murmele.Gittyup</id>
|
||||
</provides>
|
||||
|
||||
<releases>
|
||||
|
BIN
rsrc/screenshots/line-wrap-demo-2.gif
Normal file
BIN
rsrc/screenshots/line-wrap-demo-2.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 MiB |
@ -12,6 +12,7 @@ void Setting::initialize(QMap<Id, QString> &keys) {
|
||||
keys[Id::IndentWidth] = "editor/indent/width";
|
||||
keys[Id::TabWidth] = "editor/indent/tabwidth";
|
||||
keys[Id::ShowHeatmapInBlameMargin] = "editor/blame/heatmap";
|
||||
keys[Id::ShowWhitespaceInEditor] = "editor/view/showWhitespace";
|
||||
keys[Id::ColorTheme] = "window/theme";
|
||||
keys[Id::ShowFullRepoPath] = "window/path/full";
|
||||
keys[Id::HideLogAutomatically] = "window/log/hide";
|
||||
@ -19,6 +20,7 @@ void Setting::initialize(QMap<Id, QString> &keys) {
|
||||
keys[Id::OpenAllReposInTabs] = "window/tabs/repository";
|
||||
keys[Id::HideMenuBar] = "window/view/menuBarHidden";
|
||||
keys[Id::ShowAvatars] = "window/view/avatarsVisible";
|
||||
keys[Id::ShowMaximized] = "window/view/showMaximized";
|
||||
keys[Id::AutoCollapseAddedFiles] = "collapse/added";
|
||||
keys[Id::AutoCollapseDeletedFiles] = "collapse/deleted";
|
||||
keys[Id::FilemanagerCommand] = "filemanager/command";
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
IndentWidth,
|
||||
TabWidth,
|
||||
ShowHeatmapInBlameMargin,
|
||||
ShowWhitespaceInEditor,
|
||||
ColorTheme,
|
||||
ShowFullRepoPath,
|
||||
HideLogAutomatically,
|
||||
@ -43,6 +44,7 @@ public:
|
||||
OpenAllReposInTabs,
|
||||
HideMenuBar,
|
||||
ShowAvatars,
|
||||
ShowMaximized,
|
||||
AutoCollapseAddedFiles,
|
||||
AutoCollapseDeletedFiles,
|
||||
FilemanagerCommand,
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
const QString kWrapLines("diff/lines/wrap");
|
||||
const QString kIgnoreWsKey("diff/whitespace/ignore");
|
||||
const QString kLastPathKey("lastpath");
|
||||
const QString kTranslation("translation");
|
||||
@ -191,6 +192,14 @@ QString Settings::hotkey(const QString &action) const {
|
||||
return value("hotkeys/" + action, "").toString();
|
||||
}
|
||||
|
||||
bool Settings::isTextEditorWrapLines() const {
|
||||
return value(kWrapLines).toBool();
|
||||
}
|
||||
|
||||
void Settings::setTextEditorWrapLines(bool wrap) {
|
||||
setValue(kWrapLines, wrap, true);
|
||||
}
|
||||
|
||||
bool Settings::isWhitespaceIgnored() const {
|
||||
return value(kIgnoreWsKey).toBool();
|
||||
}
|
||||
|
@ -36,6 +36,10 @@ public:
|
||||
void setHotkey(const QString &action, const QString &hotkey);
|
||||
QString hotkey(const QString &action) const;
|
||||
|
||||
// wrap lines in TextEditor in DiffView
|
||||
bool isTextEditorWrapLines() const;
|
||||
void setTextEditorWrapLines(bool wrapLines);
|
||||
|
||||
// ignore whitespace
|
||||
bool isWhitespaceIgnored() const;
|
||||
void setWhitespaceIgnored(bool ignored);
|
||||
|
@ -69,8 +69,16 @@ DiffPanel::DiffPanel(const git::Repository &repo, QWidget *parent)
|
||||
}
|
||||
});
|
||||
|
||||
// Wrap lines
|
||||
QCheckBox *wrapLines = new QCheckBox(tr("Wrap lines"), this);
|
||||
wrapLines->setChecked(Settings::instance()->isTextEditorWrapLines());
|
||||
connect(wrapLines, &QCheckBox::toggled, [](bool wrap) {
|
||||
Settings::instance()->setTextEditorWrapLines(wrap);
|
||||
});
|
||||
|
||||
QFormLayout *layout = new QFormLayout(this);
|
||||
layout->addRow(tr("Context lines:"), contextLayout);
|
||||
layout->addRow(tr("Wrap lines:"), wrapLines);
|
||||
layout->addRow(tr("Character Encoding:"), encoding);
|
||||
|
||||
// Remaining settings are strictly global.
|
||||
|
@ -565,6 +565,13 @@ public:
|
||||
connect(showAvatars, &QCheckBox::toggled, [](bool checked) {
|
||||
Settings::instance()->setValue(Setting::Id::ShowAvatars, checked);
|
||||
});
|
||||
QCheckBox *showMaximized =
|
||||
new QCheckBox(tr("Show Window Maximized when opened"));
|
||||
showMaximized->setChecked(
|
||||
settings->value(Setting::Id::ShowMaximized).toBool());
|
||||
connect(showMaximized, &QCheckBox::toggled, [](bool checked) {
|
||||
Settings::instance()->setValue(Setting::Id::ShowMaximized, checked);
|
||||
});
|
||||
|
||||
QString mergeText = settings->promptDescription(Prompt::Kind::Merge);
|
||||
QCheckBox *merge = new QCheckBox(mergeText, this);
|
||||
@ -619,6 +626,7 @@ public:
|
||||
layout->addRow(QString(), repoTabs);
|
||||
layout->addRow(tr("View:"), hideMenuBar);
|
||||
layout->addRow(QString(), showAvatars);
|
||||
layout->addRow(QString(), showMaximized);
|
||||
layout->addRow(tr("Prompt:"), merge);
|
||||
layout->addRow(QString(), revert);
|
||||
layout->addRow(QString(), cherryPick);
|
||||
@ -653,6 +661,14 @@ public:
|
||||
Settings::instance()->setValue(Setting::Id::FontSize, i);
|
||||
});
|
||||
|
||||
QCheckBox *showWhitespace = new QCheckBox(tr("Show whitespace"), this);
|
||||
showWhitespace->setChecked(
|
||||
settings->value(Setting::Id::ShowWhitespaceInEditor).toBool());
|
||||
connect(showWhitespace, &QCheckBox::toggled, [](bool checked) {
|
||||
Settings::instance()->setValue(Setting::Id::ShowWhitespaceInEditor,
|
||||
checked);
|
||||
});
|
||||
|
||||
QComboBox *indent = new QComboBox(this);
|
||||
indent->addItem(tr("Tabs"));
|
||||
indent->addItem(tr("Spaces"));
|
||||
@ -687,6 +703,7 @@ public:
|
||||
QFormLayout *layout = new QFormLayout(this);
|
||||
layout->addRow(tr("Font:"), font);
|
||||
layout->addRow(tr("Font size:"), fontSize);
|
||||
layout->addRow(tr("Whitespace:"), showWhitespace);
|
||||
layout->addRow(tr("Indent using:"), indent);
|
||||
layout->addRow(tr("Indent width:"), indentWidth);
|
||||
layout->addRow(tr("Tab width:"), tabWidth);
|
||||
|
@ -76,6 +76,8 @@ TextEditor::TextEditor(QWidget *parent) : ScintillaIFace(parent) {
|
||||
setScrollWidthTracking(true);
|
||||
setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
||||
|
||||
setWrapMode(SC_WRAP_NONE);
|
||||
|
||||
setMarginLeft(4);
|
||||
setMarginTypeN(Staged, SC_MARGIN_SYMBOL);
|
||||
setMarginTypeN(LineNumber, SC_MARGIN_NUMBER);
|
||||
@ -180,6 +182,13 @@ void TextEditor::applySettings() {
|
||||
setUseTabs(settings->value(Setting::Id::UseTabsForIndent).toBool());
|
||||
setIndent(settings->value(Setting::Id::IndentWidth).toInt());
|
||||
setTabWidth(settings->value(Setting::Id::TabWidth).toInt());
|
||||
setViewWS(settings->value(Setting::Id::ShowWhitespaceInEditor).toBool());
|
||||
|
||||
if (Settings::instance()->isTextEditorWrapLines()) {
|
||||
setWrapMode(SC_WRAP_WORD);
|
||||
} else {
|
||||
setWrapMode(SC_WRAP_NONE);
|
||||
}
|
||||
|
||||
// Initialize markers.
|
||||
QColor background = palette().color(QPalette::Base);
|
||||
|
@ -154,9 +154,12 @@ Repository::operator git_repository *() const { return d->repo; }
|
||||
|
||||
QDir Repository::dir(bool includeGitFolder) const {
|
||||
QDir dir(git_repository_path(d->repo));
|
||||
if (!includeGitFolder) {
|
||||
assert(dir.dirName() == ".git");
|
||||
assert(dir.cdUp());
|
||||
if (!includeGitFolder && dir.dirName() == ".git") {
|
||||
if (!dir.cdUp()) {
|
||||
assert(false); // must be done explicit, because in release build the
|
||||
// assert will not be executed, so assert(dir.cdUp()) does
|
||||
// not work in release build
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "git/Signature.h"
|
||||
#include "git/TagRef.h"
|
||||
#include "git/Tree.h"
|
||||
#include "ui/HotkeyManager.h"
|
||||
#include <QAbstractListModel>
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
@ -185,8 +186,8 @@ public:
|
||||
|
||||
// Update status row.
|
||||
bool head = (!mRef.isValid() || mRef.isHead());
|
||||
bool valid = (mCleanStatus || !mStatus.isFinished() || status().isValid());
|
||||
if (head && valid && mPathspec.isEmpty()) {
|
||||
bool valid = (!mStatus.isFinished() || status().isValid());
|
||||
if (mShowCleanStatus && head && valid && mPathspec.isEmpty()) {
|
||||
QVector<Column> row;
|
||||
if (mGraphVisible && mRef.isValid() && mStatus.isFinished()) {
|
||||
row.append({Segment(Bottom, kTaintedColor), Segment(Dot, QColor())});
|
||||
@ -238,7 +239,7 @@ public:
|
||||
git::Config config = mRepo.appConfig();
|
||||
mRefsAll = config.value<bool>("commit.refs.all", true);
|
||||
mSortDate = config.value<bool>("commit.sort.date", true);
|
||||
mCleanStatus = config.value<bool>("commit.status.clean", false);
|
||||
mShowCleanStatus = config.value<bool>("commit.show.status", true);
|
||||
mGraphVisible = config.value<bool>("commit.graph.visible", true);
|
||||
|
||||
if (walk)
|
||||
@ -558,7 +559,7 @@ private:
|
||||
bool mSuppressResetWalker{false};
|
||||
bool mRefsAll = true;
|
||||
bool mSortDate = true;
|
||||
bool mCleanStatus = true;
|
||||
bool mShowCleanStatus = true;
|
||||
bool mGraphVisible = true;
|
||||
};
|
||||
|
||||
@ -635,9 +636,6 @@ public:
|
||||
Settings::instance()->value(Setting::Id::ShowCommitsId, true).toBool();
|
||||
LayoutConstants constants = layoutConstants(compact);
|
||||
|
||||
// Draw background.
|
||||
QStyledItemDelegate::paint(painter, opt, index);
|
||||
|
||||
bool active = (opt.state & QStyle::State_Active);
|
||||
bool selected = (opt.state & QStyle::State_Selected);
|
||||
auto group = active ? QPalette::Active : QPalette::Inactive;
|
||||
@ -646,10 +644,16 @@ public:
|
||||
QPalette palette = Application::theme()->commitList();
|
||||
QColor text = palette.color(group, textRole);
|
||||
QColor bright = palette.color(group, brightRole);
|
||||
QColor highlight = palette.color(group, QPalette::Highlight);
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHints(QPainter::Antialiasing);
|
||||
|
||||
// Draw background.
|
||||
if (selected) {
|
||||
painter->fillRect(opt.rect, highlight);
|
||||
}
|
||||
|
||||
// Draw busy indicator.
|
||||
if (opt.features & QStyleOptionViewItem::HasDecoration) {
|
||||
QRect rect = decorationRect(option, index);
|
||||
@ -784,7 +788,16 @@ public:
|
||||
// Draw content.
|
||||
git::Commit commit =
|
||||
index.data(CommitList::Role::CommitRole).value<git::Commit>();
|
||||
if (commit.isValid()) {
|
||||
if (!commit.isValid()) {
|
||||
// special case for uncommitted changes
|
||||
QString message = index.model()->data(index).toString();
|
||||
painter->save();
|
||||
QFont italic = opt.font;
|
||||
italic.setItalic(true);
|
||||
painter->setFont(italic);
|
||||
painter->drawText(opt.rect, Qt::AlignCenter, message);
|
||||
painter->restore();
|
||||
} else {
|
||||
const QFontMetrics &fm = opt.fontMetrics;
|
||||
QRect star = rect;
|
||||
|
||||
@ -829,6 +842,20 @@ public:
|
||||
rect.setWidth(rect.width() - timestampWidth - constants.hMargin);
|
||||
}
|
||||
|
||||
// Draw Name.
|
||||
if (showAuthor) {
|
||||
QString name = commit.author().name() + " ";
|
||||
painter->save();
|
||||
QFont bold = opt.font;
|
||||
bold.setBold(true);
|
||||
painter->setFont(bold);
|
||||
painter->drawText(rect, Qt::AlignRight, name);
|
||||
painter->restore();
|
||||
const QFontMetrics boldFm(bold);
|
||||
rect.setWidth(rect.width() - boldFm.horizontalAdvance(name) -
|
||||
constants.hMargin);
|
||||
}
|
||||
|
||||
// Calculate remaining width for the references.
|
||||
QRect ref = rect;
|
||||
int refsWidth = ref.width() - minWidthDesc;
|
||||
@ -847,20 +874,6 @@ public:
|
||||
badgesWidth = Badge::paint(painter, refs, ref, &opt, Qt::AlignLeft);
|
||||
rect.setX(badgesWidth); // Comes right after the badges
|
||||
|
||||
// Draw Name.
|
||||
if (showAuthor) {
|
||||
QString name = commit.author().name();
|
||||
painter->save();
|
||||
QFont bold = opt.font;
|
||||
bold.setBold(true);
|
||||
painter->setFont(bold);
|
||||
painter->drawText(rect, Qt::AlignLeft, name);
|
||||
painter->restore();
|
||||
const QFontMetrics boldFm(bold);
|
||||
rect.setX(rect.x() + boldFm.horizontalAdvance(name) +
|
||||
constants.hMargin);
|
||||
}
|
||||
|
||||
// Draw message.
|
||||
painter->save();
|
||||
painter->setPen(bright);
|
||||
@ -1156,6 +1169,12 @@ public:
|
||||
|
||||
} // namespace
|
||||
|
||||
static Hotkey selectCommitDownHotKey = HotkeyManager::registerHotkey(
|
||||
"j", "commitList/selectCommitDown", "CommitList/Select Next Commit Down");
|
||||
|
||||
static Hotkey selectCommitUpHotKey = HotkeyManager::registerHotkey(
|
||||
"k", "commitList/selectCommitUp", "CommitList/Select Next Commit Up");
|
||||
|
||||
CommitList::CommitList(Index *index, QWidget *parent)
|
||||
: QListView(parent), mIndex(index) {
|
||||
Theme *theme = Application::theme();
|
||||
@ -1211,6 +1230,15 @@ CommitList::CommitList(Index *index, QWidget *parent)
|
||||
connect(this, &CommitList::entered,
|
||||
[this](const QModelIndex &index) { update(index); });
|
||||
|
||||
QShortcut *shortcut = new QShortcut(this);
|
||||
selectCommitDownHotKey.use(shortcut);
|
||||
connect(shortcut, &QShortcut::activated, [this] { selectCommitRelative(1); });
|
||||
|
||||
shortcut = new QShortcut(this);
|
||||
selectCommitUpHotKey.use(shortcut);
|
||||
connect(shortcut, &QShortcut::activated,
|
||||
[this] { selectCommitRelative(-1); });
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
QFont font = this->font();
|
||||
font.setPointSize(13);
|
||||
@ -1333,6 +1361,19 @@ void CommitList::selectFirstCommit(bool spontaneous) {
|
||||
}
|
||||
}
|
||||
|
||||
void CommitList::selectCommitRelative(int offset) {
|
||||
QModelIndexList indices = selectionModel()->selectedIndexes();
|
||||
QModelIndex index = indices[0];
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
QModelIndex new_index = model()->index(index.row() + offset, index.column());
|
||||
if (!new_index.isValid()) {
|
||||
return;
|
||||
}
|
||||
selectIndexes(QItemSelection(new_index, new_index), QString(), true);
|
||||
}
|
||||
|
||||
bool CommitList::selectRange(const QString &range, const QString &file,
|
||||
bool spontaneous) {
|
||||
// Try to select the "status" index.
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
void selectReference(const git::Reference &ref);
|
||||
void resetSelection(bool spontaneous = false);
|
||||
void selectFirstCommit(bool spontaneous = false);
|
||||
void selectCommitRelative(int offset);
|
||||
bool selectRange(const QString &range, const QString &file = QString(),
|
||||
bool spontaneous = false);
|
||||
void suppressResetWalker(bool suppress);
|
||||
|
@ -25,7 +25,7 @@ namespace {
|
||||
const QString kRefsKey = "commit.refs.all";
|
||||
const QString kSortKey = "commit.sort.date";
|
||||
const QString kGraphKey = "commit.graph.visible";
|
||||
const QString kStatusKey = "commit.status.clean";
|
||||
const QString kStatusKey = "commit.show.status";
|
||||
const QString kStyleSheet = "QToolBar {"
|
||||
" border: none"
|
||||
"}"
|
||||
@ -155,7 +155,7 @@ CommitToolBar::CommitToolBar(QWidget *parent) : QToolBar(parent) {
|
||||
|
||||
QAction *status = menu->addAction(tr("Show Clean Status"));
|
||||
status->setCheckable(true);
|
||||
status->setChecked(config.value<bool>(kStatusKey, false));
|
||||
status->setChecked(config.value<bool>(kStatusKey, true));
|
||||
connect(status, &QAction::triggered, [this](bool checked) {
|
||||
RepoView *view = RepoView::parentView(this);
|
||||
view->repo().appConfig().setValue(kStatusKey, checked);
|
||||
|
@ -500,6 +500,7 @@ DetailView::DetailView(const git::Repository &repo, QWidget *parent)
|
||||
mDetail->setVisible(false);
|
||||
layout->addWidget(mDetail);
|
||||
|
||||
// Shown when a commit is selected
|
||||
mDetail->addWidget(new CommitDetail(this));
|
||||
|
||||
mAuthorLabel = new QLabel(this);
|
||||
@ -508,6 +509,7 @@ DetailView::DetailView(const git::Repository &repo, QWidget *parent)
|
||||
&DetailView::authorLinkActivated);
|
||||
updateAuthor();
|
||||
|
||||
// Shown when the working directory is dirty
|
||||
mCommitEditor = new CommitEditor(repo, this);
|
||||
|
||||
auto editorFrame = new QWidget(this);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "CommentWidget.h"
|
||||
#include "ui/DiffTreeModel.h"
|
||||
#include "ui/DoubleTreeWidget.h"
|
||||
#include "ui/HotkeyManager.h"
|
||||
#include "git/Tree.h"
|
||||
#include <QScrollBar>
|
||||
#include <QPushButton>
|
||||
@ -47,6 +48,12 @@ bool copy(const QString &source, const QDir &targetDir) {
|
||||
|
||||
} // namespace
|
||||
|
||||
static Hotkey moveHalfPageDownHotKey = HotkeyManager::registerHotkey(
|
||||
"d", "diffView/moveHalfPageDownHotKey", "DiffView/Move Half Page Down");
|
||||
|
||||
static Hotkey moveHalfPageUpHotKey = HotkeyManager::registerHotkey(
|
||||
"u", "diffView/moveHalfPageUpHotKey", "DiffView/Move Half Page Up");
|
||||
|
||||
DiffView::DiffView(const git::Repository &repo, QWidget *parent)
|
||||
: QScrollArea(parent), mParent(parent) {
|
||||
setStyleSheet(DiffViewStyle::kStyleSheet);
|
||||
@ -84,6 +91,14 @@ DiffView::DiffView(const git::Repository &repo, QWidget *parent)
|
||||
fetchMore();
|
||||
});
|
||||
}
|
||||
|
||||
QShortcut *shortcut = new QShortcut(this);
|
||||
moveHalfPageDownHotKey.use(shortcut);
|
||||
connect(shortcut, &QShortcut::activated, [this] { moveHalfPageDown(); });
|
||||
|
||||
shortcut = new QShortcut(this);
|
||||
moveHalfPageUpHotKey.use(shortcut);
|
||||
connect(shortcut, &QShortcut::activated, [this] { moveHalfPageUp(); });
|
||||
}
|
||||
|
||||
DiffView::~DiffView() {}
|
||||
@ -513,3 +528,13 @@ void DiffView::indexChanged(const QStringList &paths) {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void DiffView::moveHalfPageDown() { moveRelative(height() / 2); }
|
||||
|
||||
void DiffView::moveHalfPageUp() { moveRelative(-height() / 2); }
|
||||
|
||||
void DiffView::moveRelative(int pixelsDown) {
|
||||
int oldPosition = verticalScrollBar()->sliderPosition();
|
||||
int newPosition = oldPosition + pixelsDown;
|
||||
verticalScrollBar()->setSliderPosition(newPosition);
|
||||
}
|
||||
|
@ -103,6 +103,9 @@ public:
|
||||
void diffTreeModelDataChanged(const QModelIndex &topLeft,
|
||||
const QModelIndex &bottomRight,
|
||||
const QVector<int> &roles);
|
||||
void moveHalfPageDown();
|
||||
void moveHalfPageUp();
|
||||
void moveRelative(int pixelsDown);
|
||||
|
||||
signals:
|
||||
void diagnosticAdded(TextEditor::DiagnosticKind kind);
|
||||
|
@ -35,6 +35,17 @@ const QString noNewLineAtEndOfFile =
|
||||
HunkWidget::tr("No newline at end of file");
|
||||
} // namespace
|
||||
|
||||
_HunkWidget::HunkLabel::HunkLabel(const QString &name, bool submodule,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), mName(name) {}
|
||||
void _HunkWidget::HunkLabel::paintEvent(QPaintEvent *event) {
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QFontMetrics fm = fontMetrics();
|
||||
QRect rect = fm.boundingRect(0, 0, this->rect().width(), 300, 0, mName);
|
||||
painter.drawText(rect, Qt::AlignLeft | Qt::ElideRight, mName);
|
||||
}
|
||||
|
||||
_HunkWidget::Header::Header(const git::Diff &diff, const git::Patch &patch,
|
||||
int index, bool lfs, bool submodule,
|
||||
QWidget *parent)
|
||||
@ -45,9 +56,9 @@ _HunkWidget::Header::Header(const git::Diff &diff, const git::Patch &patch,
|
||||
mCheck->setVisible(diff.isStatusDiff() && !submodule &&
|
||||
!patch.isConflicted());
|
||||
|
||||
QString header = (index >= 0) ? patch.header(index) : QString();
|
||||
QString escaped = header.trimmed().toHtmlEscaped();
|
||||
QLabel *label = new QLabel(DiffViewStyle::kHunkFmt.arg(escaped), this);
|
||||
QString label_string = (index >= 0) ? patch.header(index) : QString();
|
||||
label_string = label_string.trimmed().toHtmlEscaped();
|
||||
HunkLabel *label = new HunkLabel(label_string, submodule, this);
|
||||
|
||||
if (patch.isConflicted()) {
|
||||
mSave = new QToolButton(this);
|
||||
@ -132,7 +143,7 @@ _HunkWidget::Header::Header(const git::Diff &diff, const git::Patch &patch,
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(4, 4, 4, 4);
|
||||
layout->addWidget(mCheck);
|
||||
layout->addWidget(label);
|
||||
layout->addWidget(label, 1);
|
||||
layout->addStretch();
|
||||
layout->addLayout(buttons);
|
||||
|
||||
|
@ -19,6 +19,18 @@ class DisclosureButton;
|
||||
class Line;
|
||||
|
||||
namespace _HunkWidget {
|
||||
class HunkLabel : public QWidget {
|
||||
public:
|
||||
HunkLabel(const QString &name, bool submodule, QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
QString mName;
|
||||
QString mOldName;
|
||||
};
|
||||
|
||||
class Header : public QFrame {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -201,7 +201,8 @@ void MainWindow::setSideBarVisible(bool visible) {
|
||||
splitter->setSizes({static_cast<int>(pos * value), 1});
|
||||
});
|
||||
|
||||
connect(timeline, &QTimeLine::finished, [timeline] { delete timeline; });
|
||||
connect(timeline, &QTimeLine::finished,
|
||||
[timeline] { timeline->deleteLater(); });
|
||||
|
||||
timeline->start();
|
||||
}
|
||||
@ -385,7 +386,15 @@ MainWindow *MainWindow::open(const git::Repository &repo) {
|
||||
|
||||
// Create the window.
|
||||
MainWindow *window = new MainWindow(repo);
|
||||
window->show();
|
||||
|
||||
const bool showMaximized =
|
||||
Settings::instance()->value(Setting::Id::ShowMaximized).toBool();
|
||||
|
||||
if (showMaximized) {
|
||||
window->showMaximized();
|
||||
} else {
|
||||
window->show();
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@ -890,7 +890,8 @@ void RepoView::setLogVisible(bool visible) {
|
||||
setSizes({1, static_cast<int>(pos * value)});
|
||||
});
|
||||
|
||||
connect(timeline, &QTimeLine::finished, [timeline] { delete timeline; });
|
||||
connect(timeline, &QTimeLine::finished,
|
||||
[timeline] { timeline->deleteLater(); });
|
||||
|
||||
timeline->start();
|
||||
}
|
||||
@ -1466,6 +1467,9 @@ void RepoView::rebaseConflict(const git::Rebase rebase) {
|
||||
if (mRebase) {
|
||||
mRebase->addEntry(tr("Please resolve conflicts before continue"),
|
||||
tr("Conflict"));
|
||||
mDetails->setCommitMessage(rebase.commitToRebase()
|
||||
.message(git::Commit::SubstituteEmoji)
|
||||
.trimmed());
|
||||
}
|
||||
refresh(false);
|
||||
}
|
||||
@ -2119,6 +2123,13 @@ void RepoView::dropStash(int index) {
|
||||
LogEntry *entry = addLogEntry(msg(commit), tr("Drop Stash"));
|
||||
if (!mRepo.dropStash(index))
|
||||
error(entry, tr("drop stash"), commit.link());
|
||||
|
||||
if (mRepo.stashes().size() == 0) {
|
||||
// switch back to head when there are no stashes left
|
||||
mCommits->setReference(mRepo.head());
|
||||
} else {
|
||||
mCommits->setReference(mRepo.stashRef());
|
||||
}
|
||||
}
|
||||
|
||||
void RepoView::popStash(int index) {
|
||||
@ -2131,8 +2142,9 @@ void RepoView::popStash(int index) {
|
||||
error(entry, tr("pop stash"), commit.link());
|
||||
return;
|
||||
}
|
||||
|
||||
refresh(false);
|
||||
// switch back to head
|
||||
selectReference(mRepo.head());
|
||||
selectFirstCommit();
|
||||
}
|
||||
|
||||
void RepoView::promptToAddTag(const git::Commit &commit) {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit fefb8d6acc78b5f63d5a78b86a4900e694bd2862
|
||||
Subproject commit 687b5424128fd637555be4a0d18c72c4e870bd6f
|
@ -75,6 +75,7 @@ class TestRebase : public QObject {
|
||||
private slots:
|
||||
void withoutConflicts();
|
||||
void conflictingRebase();
|
||||
void conflictingRebaseCustomMessage();
|
||||
void continueExternalStartedRebase(); // must have conflicts otherwise it is
|
||||
// not possible to continue
|
||||
void startRebaseContinueInCLI();
|
||||
@ -278,10 +279,6 @@ void TestRebase::conflictingRebase() {
|
||||
filewidgets.at(0)->stageStateChanged(filewidgets.at(0)->modelIndex(),
|
||||
git::Index::StagedState::Staged);
|
||||
|
||||
QTextEdit *editor = repoView->findChild<QTextEdit *>("MessageEditor");
|
||||
QVERIFY(editor);
|
||||
editor->setText("Test message");
|
||||
|
||||
refreshTriggered = 0;
|
||||
rebaseConflict = 0;
|
||||
repoView->continueRebase();
|
||||
@ -293,9 +290,8 @@ void TestRebase::conflictingRebase() {
|
||||
QList<Commit> parents = branch.annotatedCommit().commit().parents();
|
||||
QCOMPARE(parents.count(), 1);
|
||||
QCOMPARE(parents.at(0).id(), ac.commit().id());
|
||||
QCOMPARE(
|
||||
branch.annotatedCommit().commit().message(),
|
||||
"Test message"); // custom message was used instead of the original one
|
||||
QCOMPARE(branch.annotatedCommit().commit().message(),
|
||||
"File.txt changed by second branch"); // original message is shown
|
||||
|
||||
// Check that rebase was really finished
|
||||
QCOMPARE(mRepo.rebaseOngoing(), false);
|
||||
@ -313,6 +309,89 @@ void TestRebase::conflictingRebase() {
|
||||
QCOMPARE(rebaseConflict, 0);
|
||||
}
|
||||
|
||||
void TestRebase::conflictingRebaseCustomMessage() {
|
||||
INIT_REPO("rebaseConflicts.zip", true);
|
||||
|
||||
auto *detailview = repoView->findChild<DetailView *>();
|
||||
QVERIFY(detailview);
|
||||
auto *abortRebaseButton = detailview->findChild<QPushButton *>("AbortRebase");
|
||||
QVERIFY(abortRebaseButton);
|
||||
auto *continueRebaseButton =
|
||||
detailview->findChild<QPushButton *>("ContinueRebase");
|
||||
QVERIFY(continueRebaseButton);
|
||||
QCOMPARE(continueRebaseButton->isVisible(), false);
|
||||
QCOMPARE(abortRebaseButton->isVisible(), false);
|
||||
|
||||
const QString rebaseBranchName = "refs/heads/singleCommitConflict";
|
||||
|
||||
git::Reference branch = mRepo.lookupRef(rebaseBranchName);
|
||||
QVERIFY(branch.isValid());
|
||||
auto c = branch.annotatedCommit().commit();
|
||||
|
||||
// Checkout correct branch
|
||||
repoView->checkout(branch);
|
||||
|
||||
QTest::qWait(100);
|
||||
|
||||
// Rebase on main
|
||||
git::Reference mainBranch = mRepo.lookupRef(QString("refs/heads/main"));
|
||||
QVERIFY(mainBranch.isValid());
|
||||
auto ac = mainBranch.annotatedCommit();
|
||||
LogEntry *entry = repoView->addLogEntry("Rebase", "Rebase", nullptr);
|
||||
repoView->rebase(ac, entry);
|
||||
|
||||
QCOMPARE(mRepo.rebaseOngoing(), true);
|
||||
|
||||
// Check that buttons are visible
|
||||
QTest::qWait(100);
|
||||
|
||||
// Resolve conflicts
|
||||
diff = mRepo.status(mRepo.index(), nullptr, false);
|
||||
QCOMPARE(diff.count(), 1);
|
||||
QCOMPARE(diff.patch(0).isConflicted(), true);
|
||||
QFile f(mRepo.workdir().filePath(diff.patch(0).name()));
|
||||
QCOMPARE(f.open(QIODevice::WriteOnly), true);
|
||||
QVERIFY(f.write("Test123") !=
|
||||
-1); // just write something to resolve the conflict
|
||||
f.close();
|
||||
|
||||
QTest::qWait(100);
|
||||
|
||||
repoView->continueRebase(); // should fail
|
||||
|
||||
QTest::qWait(100); // Wait until refresh is done
|
||||
|
||||
// Staging the file
|
||||
auto filewidgets = repoView->findChildren<FileWidget *>();
|
||||
QCOMPARE(filewidgets.length(), 1);
|
||||
filewidgets.at(0)->stageStateChanged(filewidgets.at(0)->modelIndex(),
|
||||
git::Index::StagedState::Staged);
|
||||
|
||||
QTextEdit *editor = repoView->findChild<QTextEdit *>("MessageEditor");
|
||||
QVERIFY(editor);
|
||||
editor->setText("Test message"); // modify message
|
||||
|
||||
repoView->continueRebase();
|
||||
|
||||
// Check that branch is based on "main" now
|
||||
branch = mRepo.lookupRef(rebaseBranchName);
|
||||
QVERIFY(branch.isValid());
|
||||
QList<Commit> parents = branch.annotatedCommit().commit().parents();
|
||||
QCOMPARE(parents.count(), 1);
|
||||
QCOMPARE(parents.at(0).id(), ac.commit().id());
|
||||
QCOMPARE(branch.annotatedCommit().commit().message(),
|
||||
"Test message"); // Modified message is shown
|
||||
|
||||
// Check that rebase was really finished
|
||||
QCOMPARE(mRepo.rebaseOngoing(), false);
|
||||
|
||||
QTest::qWait(100); // Wait until refresh finished
|
||||
|
||||
// Check that buttons are visible
|
||||
QCOMPARE(continueRebaseButton->isVisible(), false);
|
||||
QCOMPARE(abortRebaseButton->isVisible(), false);
|
||||
}
|
||||
|
||||
void TestRebase::continueExternalStartedRebase() {
|
||||
// INIT_REPO("rebaseConflicts.zip", true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user