diff options
author | Andre Hartmann <[email protected]> | 2025-03-07 12:09:01 +0100 |
---|---|---|
committer | André Hartmann <[email protected]> | 2025-05-11 16:01:48 +0000 |
commit | b4b16a137f46dd6535bda75accf9b3a64a4e1895 (patch) | |
tree | 47c0f5d38fa3005bd482bc1cb35774eef7a3a32b /src | |
parent | fc8ce74f8aa781a9f996814abd29b5164e311c4a (diff) |
Create a temporary patch file with normalized line endings
and provide that to git.
Change-Id: Ic9eaf7970e5d27dab0fe7b436b03f1995ea5cc45
Reviewed-by: Orgad Shaneh <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/git/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/git/git.qbs | 2 | ||||
-rw-r--r-- | src/plugins/git/gitclient.cpp | 13 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.cpp | 21 | ||||
-rw-r--r-- | src/plugins/git/temporarypatchfile.cpp | 29 | ||||
-rw-r--r-- | src/plugins/git/temporarypatchfile.h | 18 |
6 files changed, 75 insertions, 9 deletions
diff --git a/src/plugins/git/CMakeLists.txt b/src/plugins/git/CMakeLists.txt index dfe6a9c05f1..742843b4058 100644 --- a/src/plugins/git/CMakeLists.txt +++ b/src/plugins/git/CMakeLists.txt @@ -37,4 +37,5 @@ add_qtc_plugin(Git remotedialog.cpp remotedialog.h remotemodel.cpp remotemodel.h stashdialog.cpp stashdialog.h + temporarypatchfile.cpp temporarypatchfile.h ) diff --git a/src/plugins/git/git.qbs b/src/plugins/git/git.qbs index 1379de7d670..4a9c70f1b8b 100644 --- a/src/plugins/git/git.qbs +++ b/src/plugins/git/git.qbs @@ -61,6 +61,8 @@ QtcPlugin { "remotemodel.h", "stashdialog.cpp", "stashdialog.h", + "temporarypatchfile.cpp", + "temporarypatchfile.h", ] Group { diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 1560536b58d..27631b1ffdc 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -11,6 +11,7 @@ #include "gittr.h" #include "gitutils.h" #include "mergetool.h" +#include "temporarypatchfile.h" #include <coreplugin/coreconstants.h> #include <coreplugin/editormanager/editormanager.h> @@ -109,21 +110,15 @@ static QString branchesDisplay(const QString &prefix, QStringList *branches, boo static void stage(DiffEditorController *diffController, const QString &patch, bool revert) { - TemporaryFile patchFile("git-patchfile"); - if (!patchFile.open()) + if (patch.isEmpty()) return; - + TemporaryPatchFile patchFile(patch); const FilePath baseDir = diffController->workingDirectory(); - QTextCodec *codec = EditorManager::defaultTextCodec(); - const QByteArray patchData = codec ? codec->fromUnicode(patch) : patch.toLocal8Bit(); - patchFile.write(patchData); - patchFile.close(); - QStringList args = {"--cached"}; if (revert) args << "--reverse"; QString errorMessage; - if (gitClient().synchronousApplyPatch(baseDir, patchFile.fileName(), + if (gitClient().synchronousApplyPatch(baseDir, patchFile.filePath().toUrlishString(), &errorMessage, args)) { if (errorMessage.isEmpty()) { if (revert) diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 05bf7016857..1de69e521a3 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -18,6 +18,7 @@ #include "logchangedialog.h" #include "remotedialog.h" #include "stashdialog.h" +#include "temporarypatchfile.h" #include "gerrit/gerritplugin.h" @@ -66,6 +67,7 @@ #include <QAction> #include <QApplication> +#include <QClipboard> #include <QDebug> #include <QDir> #include <QFileDialog> @@ -244,6 +246,7 @@ public: void cleanRepository(); void updateSubmodules(); void applyCurrentFilePatch(); + void applyClipboardPatch(); void promptApplyPatch(); void stash(bool unstagedOnly = false); @@ -840,6 +843,10 @@ GitPluginPrivate::GitPluginPrivate() Tr::tr("Apply from Editor"), Tr::tr("Apply \"%1\""), "Git.ApplyCurrentFilePatch", context, true, std::bind(&GitPluginPrivate::applyCurrentFilePatch, this)); + + createRepositoryAction(patchMenu, Tr::tr("Apply from Clipboard"), "Git.ApplyClipboardPatch", + context, true, std::bind(&GitPluginPrivate::applyClipboardPatch, this)); + createRepositoryAction(patchMenu, Tr::tr("Apply from File..."), "Git.ApplyPatch", context, true, std::bind(&GitPluginPrivate::promptApplyPatch, this)); @@ -1588,6 +1595,20 @@ void GitPluginPrivate::applyCurrentFilePatch() applyPatch(state.topLevel(), patchFile); } +void GitPluginPrivate::applyClipboardPatch() +{ + const VcsBasePluginState state = currentState(); + QTC_ASSERT(state.hasTopLevel(), return); + + QClipboard *clipboard = QApplication::clipboard(); + const QString patch = clipboard->text(); + if (patch.isEmpty()) + return; + + const TemporaryPatchFile patchFile(patch); + applyPatch(state.topLevel(), patchFile.filePath().toUrlishString()); +} + void GitPluginPrivate::promptApplyPatch() { const VcsBasePluginState state = currentState(); diff --git a/src/plugins/git/temporarypatchfile.cpp b/src/plugins/git/temporarypatchfile.cpp new file mode 100644 index 00000000000..eed28ee2ab9 --- /dev/null +++ b/src/plugins/git/temporarypatchfile.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2025 Andre Hartmann <[email protected]> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "temporarypatchfile.h" + +#include <coreplugin/editormanager/editormanager.h> + +#include <QTextCodec> + +using namespace Utils; + +TemporaryPatchFile::TemporaryPatchFile(const QString &patch) + : patchFile(new Utils::TemporaryFile("git-patchfile")) +{ + if (!patchFile->open()) + return; + + QString normalized = patch; + normalized.replace("\r\n", "\n").replace('\r', '\n'); + QTextCodec *codec = Core::EditorManager::defaultTextCodec(); + const QByteArray patchData = codec ? codec->fromUnicode(normalized) : normalized.toLocal8Bit(); + patchFile->write(patchData); + patchFile->close(); +} + +Utils::FilePath TemporaryPatchFile::filePath() const +{ + return Utils::FilePath::fromString(patchFile->fileName()); +} diff --git a/src/plugins/git/temporarypatchfile.h b/src/plugins/git/temporarypatchfile.h new file mode 100644 index 00000000000..d933b5ed169 --- /dev/null +++ b/src/plugins/git/temporarypatchfile.h @@ -0,0 +1,18 @@ +// Copyright (C) 2025 Andre Hartmann <[email protected]> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include <utils/filepath.h> +#include <utils/temporaryfile.h> + +class TemporaryPatchFile +{ +public: + TemporaryPatchFile(const QString &patch); + + Utils::FilePath filePath() const; + +private: + std::unique_ptr<Utils::TemporaryFile> patchFile; +}; |