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 <orgads@gmail.com>
This commit is contained in:
Andre Hartmann
2025-03-07 20:23:02 +01:00
committed by André Hartmann
parent 2b2d585322
commit 44b2f994df
6 changed files with 41 additions and 6 deletions

View File

@@ -14,6 +14,7 @@
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/generatedfile.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
#include <coreplugin/iversioncontrol.h> #include <coreplugin/iversioncontrol.h>
@@ -1573,6 +1574,34 @@ bool GitClient::synchronousInit(const FilePath &workingDirectory)
return false; 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: /* Checkout, supports:
* git checkout -- <files> * git checkout -- <files>
* git checkout revision -- <files> * git checkout revision -- <files>

View File

@@ -195,6 +195,7 @@ public:
bool synchronousApplyPatch(const Utils::FilePath &workingDirectory, const QString &file, bool synchronousApplyPatch(const Utils::FilePath &workingDirectory, const QString &file,
QString *errorMessage, const QStringList &extraArguments = {}) const; QString *errorMessage, const QStringList &extraArguments = {}) const;
bool synchronousInit(const Utils::FilePath &workingDirectory); bool synchronousInit(const Utils::FilePath &workingDirectory);
bool synchronousAddGitignore(const Utils::FilePath &workingDirectory);
bool synchronousCheckoutFiles(const Utils::FilePath &workingDirectory, QStringList files = {}, bool synchronousCheckoutFiles(const Utils::FilePath &workingDirectory, QStringList files = {},
QString revision = {}, QString *errorMessage = nullptr, QString revision = {}, QString *errorMessage = nullptr,
bool revertStaging = true); bool revertStaging = true);

View File

@@ -991,7 +991,7 @@ GitPluginPrivate::GitPluginPrivate()
QAction *createRepositoryAction = new QAction(Tr::tr("Create Repository..."), this); QAction *createRepositoryAction = new QAction(Tr::tr("Create Repository..."), this);
Command *createRepositoryCommand = ActionManager::registerAction( Command *createRepositoryCommand = ActionManager::registerAction(
createRepositoryAction, "Git.CreateRepository"); createRepositoryAction, "Git.CreateRepository");
connect(createRepositoryAction, &QAction::triggered, this, &GitPluginPrivate::createRepository); connect(createRepositoryAction, &QAction::triggered, this, [this] { initRepository(); });
gitContainer->addAction(createRepositoryCommand); gitContainer->addAction(createRepositoryCommand);
connect(VcsManager::instance(), &VcsManager::repositoryChanged, connect(VcsManager::instance(), &VcsManager::repositoryChanged,
@@ -1692,7 +1692,9 @@ void GitPluginPrivate::manageRemotes()
void GitPluginPrivate::initRepository() void GitPluginPrivate::initRepository()
{ {
createRepository(); Utils::FilePath topLevel;
createRepository(&topLevel);
gitClient().synchronousAddGitignore(topLevel);
} }
void GitPluginPrivate::stashList() void GitPluginPrivate::stashList()

View File

@@ -455,7 +455,7 @@ void MercurialPluginPrivate::createRepositoryActions(const Core::Context &contex
m_createRepositoryAction = new QAction(Tr::tr("Create Repository..."), this); m_createRepositoryAction = new QAction(Tr::tr("Create Repository..."), this);
command = Core::ActionManager::registerAction(m_createRepositoryAction, Utils::Id(Constants::CREATE_REPOSITORY), context); 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); m_mercurialContainer->addAction(command);
} }

View File

@@ -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; 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); QTC_ASSERT(supportsOperation(IVersionControl::CreateRepositoryOperation), return);
// Find current starting directory // Find current starting directory
@@ -673,6 +673,8 @@ void VersionControlBase::createRepository()
} while (true); } while (true);
// Create // Create
const bool rc = vcsCreateRepository(directory); const bool rc = vcsCreateRepository(directory);
if (repoDirectory)
*repoDirectory = directory;
const QString nativeDir = directory.toUserOutput(); const QString nativeDir = directory.toUserOutput();
if (rc) { if (rc) {
QMessageBox::information(mw, Tr::tr("Repository Created"), QMessageBox::information(mw, Tr::tr("Repository Created"),

View File

@@ -143,8 +143,9 @@ protected:
// delete the file via VcsManager. // delete the file via VcsManager.
void promptToDeleteCurrentFile(); void promptToDeleteCurrentFile();
// Prompt to initialize version control in a directory, initially // Prompt to initialize version control in a directory, initially
// pointing to the current project. // pointing to the current project. The optional parameter
void createRepository(); // repoDirectory is filled with the new repository toplevel dir.
void createRepository(Utils::FilePath *repoDirectory = nullptr);
enum ActionState { NoVcsEnabled, OtherVcsEnabled, VcsEnabled }; enum ActionState { NoVcsEnabled, OtherVcsEnabled, VcsEnabled };