forked from qt-creator/qt-creator
		
	Git: Handle unusual HEADs
Handle detached HEADs as well as cloning from repositories that default to another branch but master. This is relevant when clonig local repositories. Reviewed-by: Friedemann Kleint
This commit is contained in:
		@@ -45,6 +45,7 @@ struct CloneWizardPagePrivate {
 | 
			
		||||
    const QString gitPostFix;
 | 
			
		||||
    const QString protocolDelimiter;
 | 
			
		||||
    QCheckBox *deleteMasterCheckBox;
 | 
			
		||||
    QString headBranch;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CloneWizardPagePrivate::CloneWizardPagePrivate() :
 | 
			
		||||
@@ -131,33 +132,32 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizardPage::createCheckoutJob(
 | 
			
		||||
 | 
			
		||||
     const QString binary = client->binary();
 | 
			
		||||
 | 
			
		||||
     QStringList args;
 | 
			
		||||
     args << QLatin1String("clone") << repository() << checkoutDir;
 | 
			
		||||
 | 
			
		||||
     VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob;
 | 
			
		||||
     const QProcessEnvironment env = client->processEnvironment();
 | 
			
		||||
 | 
			
		||||
     // 1) Basic checkout step
 | 
			
		||||
     QStringList args;
 | 
			
		||||
     args << QLatin1String("clone") << repository() << checkoutDir;
 | 
			
		||||
     job->addStep(binary, args, workingDirectory, env);
 | 
			
		||||
     const QString checkoutBranch = branch();
 | 
			
		||||
 | 
			
		||||
     // 2) Checkout branch, change to checkoutDir
 | 
			
		||||
     const QString masterBranch = QLatin1String("master");
 | 
			
		||||
     if (!checkoutBranch.isEmpty() && checkoutBranch != masterBranch) {
 | 
			
		||||
     if (!checkoutBranch.isEmpty() && checkoutBranch != d->headBranch) {
 | 
			
		||||
         // Create branch
 | 
			
		||||
         args.clear();
 | 
			
		||||
         args << QLatin1String("branch") << QLatin1String("--track")
 | 
			
		||||
                 << checkoutBranch << (QLatin1String("origin/")  + checkoutBranch);
 | 
			
		||||
              << checkoutBranch << (QLatin1String("origin/")  + checkoutBranch);
 | 
			
		||||
         job->addStep(binary, args, *checkoutPath, env);
 | 
			
		||||
         // Checkout branch
 | 
			
		||||
         args.clear();
 | 
			
		||||
         args << QLatin1String("checkout") << checkoutBranch;
 | 
			
		||||
         job->addStep(binary, args, *checkoutPath, env);
 | 
			
		||||
         // Delete master if desired
 | 
			
		||||
         if (deleteMasterBranch()) {
 | 
			
		||||
         if (deleteMasterBranch() && d->headBranch != QLatin1String("<detached HEAD>")) {
 | 
			
		||||
             // Make sure we only have the requested branch:
 | 
			
		||||
             args.clear();
 | 
			
		||||
             args << QLatin1String("branch") << QLatin1String("-D") << masterBranch;
 | 
			
		||||
             job->addStep(binary, args, *checkoutPath, env);
 | 
			
		||||
             args << QLatin1String("branch") << QLatin1String("-D") << d->headBranch;
 | 
			
		||||
         }
 | 
			
		||||
         job->addStep(binary, args, *checkoutPath, env);
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     return QSharedPointer<VCSBase::AbstractCheckoutJob>(job);
 | 
			
		||||
@@ -166,11 +166,16 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizardPage::createCheckoutJob(
 | 
			
		||||
QStringList CloneWizardPage::branches(const QString &repository, int *current)
 | 
			
		||||
{
 | 
			
		||||
    // Run git on remote repository if an URL was specified.
 | 
			
		||||
    *current = 0;
 | 
			
		||||
    *current = -1;
 | 
			
		||||
    d->headBranch.clear();
 | 
			
		||||
 | 
			
		||||
    if (repository.isEmpty())
 | 
			
		||||
        return QStringList();
 | 
			
		||||
     const QStringList branches = Internal::GitPlugin::instance()->gitClient()->synchronousRepositoryBranches(repository);
 | 
			
		||||
     *current = branches.indexOf(QLatin1String("master"));
 | 
			
		||||
     if (!branches.isEmpty()) {
 | 
			
		||||
         *current = 0; // default branch is always returned first!
 | 
			
		||||
         d->headBranch = branches.at(0);
 | 
			
		||||
     }
 | 
			
		||||
     return branches;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1279,22 +1279,37 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Quietly retrieve branch list of remote repository URL
 | 
			
		||||
//
 | 
			
		||||
// The branch HEAD is pointing to is always returned first.
 | 
			
		||||
QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryURL)
 | 
			
		||||
{
 | 
			
		||||
    QStringList arguments(QLatin1String("ls-remote"));
 | 
			
		||||
    arguments << QLatin1String("--heads") << repositoryURL;
 | 
			
		||||
    arguments << repositoryURL << QLatin1String("HEAD") << QLatin1String("refs/heads/*");
 | 
			
		||||
    const unsigned flags =
 | 
			
		||||
            VCSBase::VCSBasePlugin::SshPasswordPrompt|
 | 
			
		||||
            VCSBase::VCSBasePlugin::SuppressStdErrInLogWindow|
 | 
			
		||||
            VCSBase::VCSBasePlugin::SuppressFailMessageInLogWindow;
 | 
			
		||||
    const Utils::SynchronousProcessResponse resp = synchronousGit(QString(), arguments, flags);
 | 
			
		||||
    QStringList branches;
 | 
			
		||||
    branches << "<detached HEAD>";
 | 
			
		||||
    QString headSha;
 | 
			
		||||
    if (resp.result == Utils::SynchronousProcessResponse::Finished) {
 | 
			
		||||
        // split "82bfad2f51d34e98b18982211c82220b8db049b<tab>refs/heads/master"
 | 
			
		||||
        foreach(const QString &line, resp.stdOut.split(QLatin1Char('\n'))) {
 | 
			
		||||
            if (line.endsWith("\tHEAD")) {
 | 
			
		||||
                Q_ASSERT(headSha.isNull());
 | 
			
		||||
                headSha = line.left(line.indexOf(QChar('\t')));
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const int slashPos = line.lastIndexOf(QLatin1Char('/'));
 | 
			
		||||
            if (slashPos != -1)
 | 
			
		||||
                branches.push_back(line.mid(slashPos + 1));
 | 
			
		||||
            const QString branchName = line.mid(slashPos + 1);
 | 
			
		||||
            if (slashPos != -1) {
 | 
			
		||||
                if (line.startsWith(headSha))
 | 
			
		||||
                    branches[0] = branchName;
 | 
			
		||||
                else
 | 
			
		||||
                    branches.push_back(branchName);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return branches;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user