From 44b2f994dfe1ea2a41d8090cf26eb00bb84e75a1 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Fri, 7 Mar 2025 20:23:02 +0100 Subject: [PATCH] Git: Add gitignore on repo creation in existing project When a git repository is created by the project wizard, the .gitignore is created from a QtCreator template and added to the "files to be committed" list. Now perform the same when creating the repository later in an already existing project directory. If the project already contains a .gitignore, then use this existing file and just mark it for committing to git. Fixes: QTCREATORBUG-29776 Change-Id: Ie153c8dfb09a5640cf79941dfe7cfb608648a4b9 Reviewed-by: Orgad Shaneh --- src/plugins/git/gitclient.cpp | 29 +++++++++++++++++++++++ src/plugins/git/gitclient.h | 1 + src/plugins/git/gitplugin.cpp | 6 +++-- src/plugins/mercurial/mercurialplugin.cpp | 2 +- src/plugins/vcsbase/vcsbaseplugin.cpp | 4 +++- src/plugins/vcsbase/vcsbaseplugin.h | 5 ++-- 6 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index bf8d11284d1..a90da569db9 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -1573,6 +1574,34 @@ bool GitClient::synchronousInit(const FilePath &workingDirectory) return false; } +bool GitClient::synchronousAddGitignore(const FilePath &workingDirectory) +{ + const FilePath gitIgnoreDestination = workingDirectory.pathAppended(".gitignore"); + + auto intentToAddGitignore = [this, workingDirectory, gitIgnoreDestination] { + return synchronousAdd(workingDirectory, {gitIgnoreDestination.fileName()}, {"--intent-to-add"}); + }; + + if (gitIgnoreDestination.exists()) + return intentToAddGitignore(); + + const FilePath gitIgnoreTemplate = + Core::ICore::resourcePath().pathAppended("templates/wizards/projects/git.ignore"); + + if (!QTC_GUARD(gitIgnoreTemplate.exists())) + return false; + + Core::GeneratedFile gitIgnoreFile(gitIgnoreDestination); + gitIgnoreFile.setBinaryContents(gitIgnoreTemplate.fileContents().value()); + QString errorMessage; + if (!gitIgnoreFile.write(&errorMessage)) { + VcsOutputWindow::appendError(errorMessage); + return false; + } + + return intentToAddGitignore(); +} + /* Checkout, supports: * git checkout -- * git checkout revision -- diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index f2f8e93be99..cb022027bab 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -195,6 +195,7 @@ public: bool synchronousApplyPatch(const Utils::FilePath &workingDirectory, const QString &file, QString *errorMessage, const QStringList &extraArguments = {}) const; bool synchronousInit(const Utils::FilePath &workingDirectory); + bool synchronousAddGitignore(const Utils::FilePath &workingDirectory); bool synchronousCheckoutFiles(const Utils::FilePath &workingDirectory, QStringList files = {}, QString revision = {}, QString *errorMessage = nullptr, bool revertStaging = true); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 487fd00d097..866ecb95be7 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -991,7 +991,7 @@ GitPluginPrivate::GitPluginPrivate() QAction *createRepositoryAction = new QAction(Tr::tr("Create Repository..."), this); Command *createRepositoryCommand = ActionManager::registerAction( createRepositoryAction, "Git.CreateRepository"); - connect(createRepositoryAction, &QAction::triggered, this, &GitPluginPrivate::createRepository); + connect(createRepositoryAction, &QAction::triggered, this, [this] { initRepository(); }); gitContainer->addAction(createRepositoryCommand); connect(VcsManager::instance(), &VcsManager::repositoryChanged, @@ -1692,7 +1692,9 @@ void GitPluginPrivate::manageRemotes() void GitPluginPrivate::initRepository() { - createRepository(); + Utils::FilePath topLevel; + createRepository(&topLevel); + gitClient().synchronousAddGitignore(topLevel); } void GitPluginPrivate::stashList() diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp index 531920b1ff6..23f80549174 100644 --- a/src/plugins/mercurial/mercurialplugin.cpp +++ b/src/plugins/mercurial/mercurialplugin.cpp @@ -455,7 +455,7 @@ void MercurialPluginPrivate::createRepositoryActions(const Core::Context &contex m_createRepositoryAction = new QAction(Tr::tr("Create Repository..."), this); command = Core::ActionManager::registerAction(m_createRepositoryAction, Utils::Id(Constants::CREATE_REPOSITORY), context); - connect(m_createRepositoryAction, &QAction::triggered, this, &MercurialPluginPrivate::createRepository); + connect(m_createRepositoryAction, &QAction::triggered, this, [this] { createRepository(); }); m_mercurialContainer->addAction(command); } diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp index f5e14f4316a..19d6f652a43 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.cpp +++ b/src/plugins/vcsbase/vcsbaseplugin.cpp @@ -648,7 +648,7 @@ static inline bool ask(QWidget *parent, const QString &title, const QString &que return QMessageBox::question(parent, title, question, QMessageBox::Yes|QMessageBox::No, defaultButton) == QMessageBox::Yes; } -void VersionControlBase::createRepository() +void VersionControlBase::createRepository(FilePath *repoDirectory) { QTC_ASSERT(supportsOperation(IVersionControl::CreateRepositoryOperation), return); // Find current starting directory @@ -673,6 +673,8 @@ void VersionControlBase::createRepository() } while (true); // Create const bool rc = vcsCreateRepository(directory); + if (repoDirectory) + *repoDirectory = directory; const QString nativeDir = directory.toUserOutput(); if (rc) { QMessageBox::information(mw, Tr::tr("Repository Created"), diff --git a/src/plugins/vcsbase/vcsbaseplugin.h b/src/plugins/vcsbase/vcsbaseplugin.h index 3505f41d160..73f50836a3b 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.h +++ b/src/plugins/vcsbase/vcsbaseplugin.h @@ -143,8 +143,9 @@ protected: // delete the file via VcsManager. void promptToDeleteCurrentFile(); // Prompt to initialize version control in a directory, initially - // pointing to the current project. - void createRepository(); + // pointing to the current project. The optional parameter + // repoDirectory is filled with the new repository toplevel dir. + void createRepository(Utils::FilePath *repoDirectory = nullptr); enum ActionState { NoVcsEnabled, OtherVcsEnabled, VcsEnabled };