Exemplo n.º 1
0
bool PasteMoveCommand::Execute()
{
    CString sDroppath = parser.GetVal(L"droptarget");
    CTSVNPath dropPath(sDroppath);
    ProjectProperties props;
    props.ReadProps(dropPath);
    if (dropPath.IsAdminDir())
        return FALSE;
    SVN svn;
    SVNStatus status;
    unsigned long count = 0;
    pathList.RemoveAdminPaths();
    CString sNewName;
    CProgressDlg progress;
    progress.SetTitle(IDS_PROC_MOVING);
    progress.SetTime(true);
    progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
    for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
    {
        CTSVNPath destPath;
        if (sNewName.IsEmpty())
            destPath = CTSVNPath(sDroppath+L"\\"+pathList[nPath].GetFileOrDirectoryName());
        else
            destPath = CTSVNPath(sDroppath+L"\\"+sNewName);
        if (destPath.Exists())
        {
            CString name = pathList[nPath].GetFileOrDirectoryName();
            if (!sNewName.IsEmpty())
                name = sNewName;
            progress.Stop();
            CRenameDlg dlg;
            dlg.SetFileSystemAutoComplete();
            dlg.m_name = name;
            dlg.SetInputValidator(this);
            m_renPath = pathList[nPath];
            dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name);
            if (dlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            destPath.SetFromWin(sDroppath+L"\\"+dlg.m_name);
        }
        svn_wc_status_kind s = status.GetAllStatus(pathList[nPath]);
        if ((s == svn_wc_status_none)||(s == svn_wc_status_unversioned)||(s == svn_wc_status_ignored))
        {
            // source file is unversioned: move the file to the target, then add it
            MoveFile(pathList[nPath].GetWinPath(), destPath.GetWinPath());
            if (!svn.Add(CTSVNPathList(destPath), &props, svn_depth_infinity, true, true, false, true))
            {
                svn.ShowErrorDialog(GetExplorerHWND());
                return FALSE;       //get out of here
            }
            CShellUpdater::Instance().AddPathForUpdate(destPath);
        }
        else
        {
            if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath))
            {
                svn.ShowErrorDialog(GetExplorerHWND());
                return FALSE;       //get out of here
            }
            else
                CShellUpdater::Instance().AddPathForUpdate(destPath);
        }
        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, pathList[nPath].GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath());
            progress.SetProgress(count, pathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            TaskDialog(GetExplorerHWND(), AfxGetResourceHandle(), MAKEINTRESOURCE(IDS_APPNAME), MAKEINTRESOURCE(IDS_SVN_USERCANCELLED), NULL, TDCBF_OK_BUTTON, TD_INFORMATION_ICON, NULL);
            return FALSE;
        }
    }
    return true;
}
bool DropExternalCommand::Execute()
{
    bool bSuccess = false;
    CString droppath = parser.GetVal(L"droptarget");
    CTSVNPath droptsvnpath = CTSVNPath(droppath);
    if (droptsvnpath.IsAdminDir())
        droptsvnpath = droptsvnpath.GetDirectory();
    if (!droptsvnpath.IsDirectory())
        droptsvnpath = droptsvnpath.GetDirectory();

    // first get the svn:externals property from the target folder
    SVNProperties props(droptsvnpath, SVNRev::REV_WC, false, false);
    std::string sExternalsValue;
    for (int i = 0; i < props.GetCount(); ++i)
    {
        if (props.GetItemName(i).compare(SVN_PROP_EXTERNALS) == 0)
        {
            sExternalsValue = props.GetItemValue(i);
            break;
        }
    }

    // we don't add admin dirs as externals
    pathList.RemoveAdminPaths();
    if (pathList.GetCount() == 0)
        return bSuccess;

    SVNStatus status;
    status.GetStatus(droptsvnpath);
    CString sTargetRepoRootUrl;
    if (status.status && status.status->repos_root_url)
    {
        sTargetRepoRootUrl = CUnicodeUtils::GetUnicode(status.status->repos_root_url);
    }
    if (sTargetRepoRootUrl.IsEmpty())
    {
        // failed to get the status and/or the repo root url
        CString messageString;
        messageString.Format(IDS_ERR_NOURLOFFILE, droptsvnpath.GetWinPath());
        ::MessageBox(GetExplorerHWND(), messageString, L"TortoiseSVN", MB_ICONERROR);
    }
    SVN svn;
    for (auto i = 0; i < pathList.GetCount(); ++i)
    {
        CTSVNPath destPath = droptsvnpath;
        destPath.AppendPathString(pathList[i].GetFileOrDirectoryName());
        bool bExists = !!PathFileExists(destPath.GetWinPath());
        if (!bExists &&
            (PathIsDirectory(pathList[i].GetWinPath()) || CopyFile(pathList[i].GetWinPath(), destPath.GetWinPath(), TRUE)))
        {
            SVNStatus sourceStatus;
            sourceStatus.GetStatus(pathList[i]);
            if (sourceStatus.status && sourceStatus.status->repos_root_url)
            {
                CString sExternalRootUrl = CUnicodeUtils::GetUnicode(sourceStatus.status->repos_root_url);
                CString sExternalUrl = svn.GetURLFromPath(pathList[i]);
                CString sExtValue = sExternalUrl + L" " + pathList[i].GetFileOrDirectoryName();
                // check if the url is from the same repo as the target, and if it is
                // use a relative external url instead of a full url
                if (sTargetRepoRootUrl.Compare(sExternalRootUrl) == 0)
                {
                    sExtValue = L"^" + sExternalUrl.Mid(sTargetRepoRootUrl.GetLength()) + L" " + pathList[i].GetFileOrDirectoryName();
                }
                if (!sExternalsValue.empty())
                {
                    if (sExternalsValue[sExternalsValue.size() - 1] != '\n')
                        sExternalsValue += "\n";
                }
                sExternalsValue += CUnicodeUtils::StdGetUTF8((LPCWSTR)sExtValue);
                bSuccess = true;
            }
        }
        else
        {
            // the file already exists, there can't be an external with the
            // same name.

            CString messageString;
            messageString.Format(IDS_DROPEXT_FILEEXISTS, (LPCWSTR)pathList[i].GetFileOrDirectoryName());
            ::MessageBox(GetExplorerHWND(), messageString, L"TortoiseSVN", MB_ICONERROR);
            bSuccess = false;
        }
    }
    if (bSuccess)
    {
        bSuccess = !!props.Add(SVN_PROP_EXTERNALS, sExternalsValue, true);
        if (bSuccess)
        {
            CString sInfo;
            sInfo.Format(IDS_DROPEXT_UPDATE_TASK1, (LPCTSTR)droptsvnpath.GetFileOrDirectoryName());
            CTaskDialog taskdlg(sInfo,
                                CString(MAKEINTRESOURCE(IDS_DROPEXT_UPDATE_TASK2)),
                                L"TortoiseSVN",
                                0,
                                TDF_ENABLE_HYPERLINKS | TDF_USE_COMMAND_LINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_SIZE_TO_CONTENT);
            taskdlg.AddCommandControl(1, CString(MAKEINTRESOURCE(IDS_DROPEXT_UPDATE_TASK3)));
            taskdlg.AddCommandControl(2, CString(MAKEINTRESOURCE(IDS_DROPEXT_UPDATE_TASK4)));
            taskdlg.SetCommonButtons(TDCBF_CANCEL_BUTTON);
            taskdlg.SetDefaultCommandControl(2);
            taskdlg.SetMainIcon(TD_WARNING_ICON);
            bool doUpdate = (taskdlg.DoModal(GetExplorerHWND()) == 1);
            if (doUpdate)
            {
                DWORD exitcode = 0;
                CString error;
                ProjectProperties pprops;
                pprops.ReadPropsPathList(pathList);
                CHooks::Instance().SetProjectProperties(droptsvnpath, pprops);
                if (CHooks::Instance().StartUpdate(GetExplorerHWND(), pathList, exitcode, error))
                {
                    if (exitcode)
                    {
                        CString temp;
                        temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);
                        ::MessageBox(GetExplorerHWND(), temp, L"TortoiseSVN", MB_ICONERROR);
                        return FALSE;
                    }
                }

                CSVNProgressDlg progDlg;
                theApp.m_pMainWnd = &progDlg;
                progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Update);
                progDlg.SetAutoClose(parser);
                progDlg.SetOptions(ProgOptSkipPreChecks);
                progDlg.SetPathList(CTSVNPathList(droptsvnpath));
                progDlg.SetRevision(SVNRev(L"HEAD"));
                progDlg.SetProjectProperties(pprops);
                progDlg.SetDepth(svn_depth_unknown);
                progDlg.DoModal();
                return !progDlg.DidErrorsOccur();
            }
        }
        else
        {
            // adding the svn:externals property failed, remove all the copied files
            props.ShowErrorDialog(GetExplorerHWND());
        }
    }

    return bSuccess != false;
}
Exemplo n.º 3
0
bool SVNDiff::DiffProps(const CTSVNPath& filePath, const SVNRev& rev1, const SVNRev& rev2, svn_revnum_t &baseRev) const
{
    bool retvalue = false;
    // diff the properties
    SVNProperties propswc(filePath, rev1, false, false);
    SVNProperties propsbase(filePath, rev2, false, false);

#define MAX_PATH_LENGTH 80
    WCHAR pathbuf1[MAX_PATH] = {0};
    if (filePath.GetWinPathString().GetLength() >= MAX_PATH)
    {
        std::wstring str = filePath.GetWinPath();
        std::wregex rx(L"^(\\w+:|(?:\\\\|/+))((?:\\\\|/+)[^\\\\/]+(?:\\\\|/)[^\\\\/]+(?:\\\\|/)).*((?:\\\\|/)[^\\\\/]+(?:\\\\|/)[^\\\\/]+)$");
        std::wstring replacement = L"$1$2...$3";
        std::wstring str2 = std::regex_replace(str, rx, replacement);
        if (str2.size() >= MAX_PATH)
            str2 = str2.substr(0, MAX_PATH-2);
        PathCompactPathEx(pathbuf1, str2.c_str(), MAX_PATH_LENGTH, 0);
    }
    else
        PathCompactPathEx(pathbuf1, filePath.GetWinPath(), MAX_PATH_LENGTH, 0);

    if ((baseRev == 0) && (!filePath.IsUrl()) && (rev1.IsBase() || rev2.IsBase()))
    {
        SVNStatus stat;
        CTSVNPath dummy;
        svn_client_status_t * s = stat.GetFirstFileStatus(filePath, dummy);
        if (s)
            baseRev = s->revision;
    }
    // check for properties that got removed
    for (int baseindex = 0; baseindex < propsbase.GetCount(); ++baseindex)
    {
        std::string basename = propsbase.GetItemName(baseindex);
        tstring basenameU = CUnicodeUtils::StdGetUnicode(basename);
        tstring basevalue = (LPCTSTR)CUnicodeUtils::GetUnicode(propsbase.GetItemValue(baseindex).c_str());
        bool bFound = false;
        for (int wcindex = 0; wcindex < propswc.GetCount(); ++wcindex)
        {
            if (basename.compare (propswc.GetItemName(wcindex))==0)
            {
                bFound = true;
                break;
            }
        }
        if (!bFound)
        {
            // write the old property value to temporary file
            CTSVNPath wcpropfile = CTempFiles::Instance().GetTempFilePath(false);
            CTSVNPath basepropfile = CTempFiles::Instance().GetTempFilePath(false);
            FILE * pFile;
            _tfopen_s(&pFile, wcpropfile.GetWinPath(), L"wb");
            if (pFile)
            {
                fclose(pFile);
                FILE * pFile2;
                _tfopen_s(&pFile2, basepropfile.GetWinPath(), L"wb");
                if (pFile2)
                {
                    fputs(CUnicodeUtils::StdGetUTF8(basevalue).c_str(), pFile2);
                    fclose(pFile2);
                }
                else
                    return false;
            }
            else
                return false;
            SetFileAttributes(wcpropfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);
            SetFileAttributes(basepropfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);
            CString n1, n2;
            bool bSwitch = false;
            if (rev1.IsWorking())
                n1.Format(IDS_DIFF_PROP_WCNAME, basenameU.c_str());
            if (rev1.IsBase())
            {
                if (baseRev)
                    n1.FormatMessage(IDS_DIFF_PROP_BASENAMEREV, basenameU.c_str(), baseRev);
                else
                    n1.Format(IDS_DIFF_PROP_BASENAME, basenameU.c_str());
            }
            if (rev1.IsHead())
                n1.Format(IDS_DIFF_PROP_REMOTENAME, basenameU.c_str());
            if (n1.IsEmpty())
            {
                CString temp;
                temp.Format(IDS_DIFF_REVISIONPATCHED, (LONG)rev1);
                n1 = basenameU.c_str();
                n1 += L" " + temp;
                bSwitch = true;
            }
            else
            {
                n1 = CString(pathbuf1) + L" - " + n1;
            }
            if (rev2.IsWorking())
                n2.Format(IDS_DIFF_PROP_WCNAME, basenameU.c_str());
            if (rev2.IsBase())
            {
                if (baseRev)
                    n2.FormatMessage(IDS_DIFF_PROP_BASENAMEREV, basenameU.c_str(), baseRev);
                else
                    n2.Format(IDS_DIFF_PROP_BASENAME, basenameU.c_str());
            }
            if (rev2.IsHead())
                n2.Format(IDS_DIFF_PROP_REMOTENAME, basenameU.c_str());
            if (n2.IsEmpty())
            {
                CString temp;
                temp.Format(IDS_DIFF_REVISIONPATCHED, (LONG)rev2);
                n2 = basenameU.c_str();
                n2 += L" " + temp;
                bSwitch = true;
            }
            else
            {
                n2 = CString(pathbuf1) + L" - " + n2;
            }
            if (bSwitch)
            {
                retvalue = !!CAppUtils::StartExtDiffProps(wcpropfile, basepropfile, n1, n2, TRUE, TRUE);
            }
            else
            {
                retvalue = !!CAppUtils::StartExtDiffProps(basepropfile, wcpropfile, n2, n1, TRUE, TRUE);
            }
        }
    }

    for (int wcindex = 0; wcindex < propswc.GetCount(); ++wcindex)
    {
        std::string wcname = propswc.GetItemName(wcindex);
        tstring wcnameU = CUnicodeUtils::StdGetUnicode(wcname);
        tstring wcvalue = (LPCTSTR)CUnicodeUtils::GetUnicode(propswc.GetItemValue(wcindex).c_str());
        tstring basevalue;
        bool bDiffRequired = true;
        for (int baseindex = 0; baseindex < propsbase.GetCount(); ++baseindex)
        {
            if (propsbase.GetItemName(baseindex).compare(wcname)==0)
            {
                basevalue = CUnicodeUtils::GetUnicode(propsbase.GetItemValue(baseindex).c_str());
                if (basevalue.compare(wcvalue)==0)
                {
                    // name and value are identical
                    bDiffRequired = false;
                    break;
                }
            }
        }
        if (bDiffRequired)
        {
            // write both property values to temporary files
            CTSVNPath wcpropfile = CTempFiles::Instance().GetTempFilePath(false);
            CTSVNPath basepropfile = CTempFiles::Instance().GetTempFilePath(false);
            FILE * pFile;
            _tfopen_s(&pFile, wcpropfile.GetWinPath(), L"wb");
            if (pFile)
            {
                fputs(CUnicodeUtils::StdGetUTF8(wcvalue).c_str(), pFile);
                fclose(pFile);
                FILE * pFile2;
                _tfopen_s(&pFile2, basepropfile.GetWinPath(), L"wb");
                if (pFile2)
                {
                    fputs(CUnicodeUtils::StdGetUTF8(basevalue).c_str(), pFile2);
                    fclose(pFile2);
                }
                else
                    return false;
            }
            else
                return false;
            SetFileAttributes(wcpropfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);
            SetFileAttributes(basepropfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);
            CString n1, n2;
            if (rev1.IsWorking())
                n1.Format(IDS_DIFF_WCNAME, wcnameU.c_str());
            if (rev1.IsBase())
                n1.Format(IDS_DIFF_BASENAME, wcnameU.c_str());
            if (rev1.IsHead())
                n1.Format(IDS_DIFF_REMOTENAME, wcnameU.c_str());
            if (n1.IsEmpty())
                n1.FormatMessage(IDS_DIFF_PROP_REVISIONNAME, wcnameU.c_str(), (LPCTSTR)rev1.ToString());
            else
                n1 = CString(pathbuf1) + L" - " + n1;
            if (rev2.IsWorking())
                n2.Format(IDS_DIFF_WCNAME, wcnameU.c_str());
            if (rev2.IsBase())
                n2.Format(IDS_DIFF_BASENAME, wcnameU.c_str());
            if (rev2.IsHead())
                n2.Format(IDS_DIFF_REMOTENAME, wcnameU.c_str());
            if (n2.IsEmpty())
                n2.FormatMessage(IDS_DIFF_PROP_REVISIONNAME, wcnameU.c_str(), (LPCTSTR)rev2.ToString());
            else
                n2 = CString(pathbuf1) + L" - " + n2;
            retvalue = !!CAppUtils::StartExtDiffProps(basepropfile, wcpropfile, n2, n1, TRUE, TRUE);
        }
    }
    return retvalue;
}
Exemplo n.º 4
0
bool SVNDiff::DiffWCFile(const CTSVNPath& filePath,
                         bool ignoreprops,
                         svn_wc_status_kind status, /* = svn_wc_status_none */
                         svn_wc_status_kind text_status /* = svn_wc_status_none */,
                         svn_wc_status_kind prop_status /* = svn_wc_status_none */,
                         svn_wc_status_kind remotetext_status /* = svn_wc_status_none */,
                         svn_wc_status_kind remoteprop_status /* = svn_wc_status_none */)
{
    CTSVNPath basePath;
    CTSVNPath remotePath;
    SVNRev remoteRev;
    svn_revnum_t baseRev = 0;

    // first diff the remote properties against the wc props
    // TODO: should we attempt to do a three way diff with the properties too
    // if they're modified locally and remotely?
    if (!ignoreprops && (remoteprop_status > svn_wc_status_normal))
    {
        DiffProps(filePath, SVNRev::REV_HEAD, SVNRev::REV_WC, baseRev);
    }
    if (!ignoreprops && (prop_status > svn_wc_status_normal)&&(filePath.IsDirectory()))
    {
        DiffProps(filePath, SVNRev::REV_WC, SVNRev::REV_BASE, baseRev);
    }
    if (filePath.IsDirectory())
        return true;

    if ((status > svn_wc_status_normal) || (text_status > svn_wc_status_normal))
    {
        basePath = SVN::GetPristinePath(filePath);
        if (baseRev == 0)
        {
            SVNStatus stat;
            CTSVNPath dummy;
            svn_client_status_t * s = stat.GetFirstFileStatus(filePath, dummy);
            if (s)
                baseRev = s->revision >= 0 ? s->revision : s->changed_rev;
        }
        // If necessary, convert the line-endings on the file before diffing
        if ((DWORD)CRegDWORD(L"Software\\TortoiseSVN\\ConvertBase", TRUE))
        {
            CTSVNPath temporaryFile = CTempFiles::Instance().GetTempFilePath(m_bRemoveTempFiles, filePath, SVNRev::REV_BASE);
            if (!m_pSVN->Export(filePath, temporaryFile, SVNRev(SVNRev::REV_BASE), SVNRev(SVNRev::REV_BASE)))
            {
                temporaryFile.Reset();
            }
            else
            {
                basePath = temporaryFile;
                SetFileAttributes(basePath.GetWinPath(), FILE_ATTRIBUTE_READONLY);
            }
        }
    }

    if (remotetext_status > svn_wc_status_normal)
    {
        remotePath = CTempFiles::Instance().GetTempFilePath(false, filePath, SVNRev::REV_HEAD);

        CProgressDlg progDlg;
        progDlg.SetTitle(IDS_APPNAME);
        progDlg.SetTime(false);
        m_pSVN->SetAndClearProgressInfo(&progDlg, true);    // activate progress bar
        progDlg.ShowModeless(GetHWND());
        progDlg.FormatPathLine(1, IDS_PROGRESSGETFILE, (LPCTSTR)filePath.GetUIFileOrDirectoryName());
        remoteRev = SVNRev::REV_HEAD;
        if (!m_pSVN->Export(filePath, remotePath, remoteRev, remoteRev))
        {
            progDlg.Stop();
            m_pSVN->SetAndClearProgressInfo((HWND)NULL);
            m_pSVN->ShowErrorDialog(GetHWND());
            return false;
        }
        progDlg.Stop();
        m_pSVN->SetAndClearProgressInfo((HWND)NULL);
        SetFileAttributes(remotePath.GetWinPath(), FILE_ATTRIBUTE_READONLY);
    }

    CString name = filePath.GetUIFileOrDirectoryName();
    CString n1, n2, n3;
    n1.Format(IDS_DIFF_WCNAME, (LPCTSTR)name);
    if (baseRev)
        n2.FormatMessage(IDS_DIFF_BASENAMEREV, (LPCTSTR)name, baseRev);
    else
        n2.Format(IDS_DIFF_BASENAME, (LPCTSTR)name);
    n3.Format(IDS_DIFF_REMOTENAME, (LPCTSTR)name);

    if ((text_status <= svn_wc_status_normal)&&(prop_status <= svn_wc_status_normal)&&(status <= svn_wc_status_normal))
    {
        // Hasn't changed locally - diff remote against WC
        return CAppUtils::StartExtDiff(
            filePath, remotePath, n1, n3, filePath, filePath, SVNRev::REV_WC, remoteRev, remoteRev, CAppUtils::DiffFlags().AlternativeTool(m_bAlternativeTool),
            m_JumpLine, filePath.GetFileOrDirectoryName(), L"");
    }
    else if (remotePath.IsEmpty())
    {
        return DiffFileAgainstBase(filePath, baseRev, ignoreprops, status, text_status, prop_status);
    }
    else
    {
        // Three-way diff
        CAppUtils::MergeFlags flags;
        flags.bAlternativeTool = m_bAlternativeTool;
        flags.bReadOnly = true;
        return !!CAppUtils::StartExtMerge(flags,
            basePath, remotePath, filePath, CTSVNPath(), false, n2, n3, n1, CString(), filePath.GetFileOrDirectoryName());
    }
}
Exemplo n.º 5
0
bool SVNDiff::DiffFileAgainstBase( const CTSVNPath& filePath, svn_revnum_t & baseRev, bool ignoreprops, svn_wc_status_kind status /*= svn_wc_status_none*/, svn_wc_status_kind text_status /*= svn_wc_status_none*/, svn_wc_status_kind prop_status /*= svn_wc_status_none*/ )
{
    bool retvalue = false;
    bool fileexternal = false;
    if ((text_status == svn_wc_status_none)||(prop_status == svn_wc_status_none))
    {
        SVNStatus stat;
        stat.GetStatus(filePath);
        if (stat.status == NULL)
            return false;
        text_status = stat.status->text_status;
        prop_status = stat.status->prop_status;
        fileexternal = stat.status->file_external != 0;
    }
    if (!ignoreprops && (prop_status > svn_wc_status_normal))
    {
        DiffProps(filePath, SVNRev::REV_WC, SVNRev::REV_BASE, baseRev);
    }

    if (filePath.IsDirectory())
        return true;
    if ((status >= svn_wc_status_normal) || (text_status >= svn_wc_status_normal))
    {
        CTSVNPath basePath(SVN::GetPristinePath(filePath));
        if (baseRev == 0)
        {
            SVNInfo info;
            const SVNInfoData * infodata = info.GetFirstFileInfo(filePath, SVNRev(), SVNRev());

            if (infodata)
            {
                if (infodata->copyfromurl && infodata->copyfromurl[0])
                    baseRev = infodata->copyfromrev;
                else
                    baseRev = infodata->lastchangedrev;
            }
        }
        // If necessary, convert the line-endings on the file before diffing
        // note: file externals can not be exported
        if (((DWORD)CRegDWORD(L"Software\\TortoiseSVN\\ConvertBase", TRUE)) && (!fileexternal))
        {
            CTSVNPath temporaryFile = CTempFiles::Instance().GetTempFilePath(m_bRemoveTempFiles, filePath, SVNRev::REV_BASE);
            if (!m_pSVN->Export(filePath, temporaryFile, SVNRev(SVNRev::REV_BASE), SVNRev(SVNRev::REV_BASE)))
            {
                temporaryFile.Reset();
            }
            else
            {
                basePath = temporaryFile;
                SetFileAttributes(basePath.GetWinPath(), FILE_ATTRIBUTE_READONLY);
            }
        }
        // for added/deleted files, we don't have a BASE file.
        // create an empty temp file to be used.
        if (!basePath.Exists())
        {
            basePath = CTempFiles::Instance().GetTempFilePath(m_bRemoveTempFiles, filePath, SVNRev::REV_BASE);
            SetFileAttributes(basePath.GetWinPath(), FILE_ATTRIBUTE_READONLY);
        }
        CString name = filePath.GetFilename();
        CTSVNPath wcFilePath = filePath;
        if (!wcFilePath.Exists())
        {
            wcFilePath = CTempFiles::Instance().GetTempFilePath(m_bRemoveTempFiles, filePath, SVNRev::REV_BASE);
            SetFileAttributes(wcFilePath.GetWinPath(), FILE_ATTRIBUTE_READONLY);
        }
        CString n1, n2;
        n1.Format(IDS_DIFF_WCNAME, (LPCTSTR)name);
        if (baseRev)
            n2.FormatMessage(IDS_DIFF_BASENAMEREV, (LPCTSTR)name, baseRev);
        else
            n2.Format(IDS_DIFF_BASENAME, (LPCTSTR)name);
        retvalue = CAppUtils::StartExtDiff(
            basePath, wcFilePath, n2, n1,
            filePath, filePath, SVNRev::REV_BASE, SVNRev::REV_WC, SVNRev::REV_BASE,
            CAppUtils::DiffFlags().Wait().AlternativeTool(m_bAlternativeTool), m_JumpLine, name, L"");
    }
    return retvalue;
}
Exemplo n.º 6
0
bool ConflictEditorCommand::Execute()
{
	CTSVNPath merge = cmdLinePath;
	CTSVNPath directory = merge.GetDirectory();
	bool bRet = false;
	bool bAlternativeTool = !!parser.HasKey(_T("alternative"));

	// we have the conflicted file (%merged)
	// now look for the other required files
	SVNStatus stat;
	stat.GetStatus(merge);
	if (stat.status == NULL)
		return false;

	if (stat.status->text_status == svn_wc_status_conflicted)
	{
		// we have a text conflict, use our merge tool to resolve the conflict

		CTSVNPath theirs(directory);
		CTSVNPath mine(directory);
		CTSVNPath base(directory);
		bool bConflictData = false;

		if ((stat.status->entry)&&(stat.status->entry->conflict_new))
		{
			theirs.AppendPathString(CUnicodeUtils::GetUnicode(stat.status->entry->conflict_new));
			bConflictData = true;
		}
		if ((stat.status->entry)&&(stat.status->entry->conflict_old))
		{
			base.AppendPathString(CUnicodeUtils::GetUnicode(stat.status->entry->conflict_old));
			bConflictData = true;
		}
		if ((stat.status->entry)&&(stat.status->entry->conflict_wrk))
		{
			mine.AppendPathString(CUnicodeUtils::GetUnicode(stat.status->entry->conflict_wrk));
			bConflictData = true;
		}
		else
		{
			mine = merge;
		}
		if (bConflictData)
			bRet = !!CAppUtils::StartExtMerge(CAppUtils::MergeFlags().AlternativeTool(bAlternativeTool), 
												base, theirs, mine, merge);
	}

	if (stat.status->prop_status == svn_wc_status_conflicted)
	{
		// we have a property conflict
		CTSVNPath prej(directory);
		if ((stat.status->entry)&&(stat.status->entry->prejfile))
		{
			prej.AppendPathString(CUnicodeUtils::GetUnicode(stat.status->entry->prejfile));
			// there's a problem: the prej file contains a _description_ of the conflict, and
			// that description string might be translated. That means we have no way of parsing
			// the file to find out the conflicting values.
			// The only thing we can do: show a dialog with the conflict description, then
			// let the user either accept the existing property or open the property edit dialog
			// to manually change the properties and values. And a button to mark the conflict as
			// resolved.
			CEditPropConflictDlg dlg;
			dlg.SetPrejFile(prej);
			dlg.SetConflictedItem(merge);
			bRet = (dlg.DoModal() != IDCANCEL);
		}
	}

	if (stat.status->tree_conflict)
	{
		// we have a tree conflict
		SVNInfo info;
		const SVNInfoData * pInfoData = info.GetFirstFileInfo(merge, SVNRev(), SVNRev());
		if (pInfoData)
		{
			if (pInfoData->treeconflict_kind == svn_wc_conflict_kind_text)
			{
				CTSVNPath theirs(directory);
				CTSVNPath mine(directory);
				CTSVNPath base(directory);
				bool bConflictData = false;

				if (pInfoData->treeconflict_theirfile)
				{
					theirs.AppendPathString(pInfoData->treeconflict_theirfile);
					bConflictData = true;
				}
				if (pInfoData->treeconflict_basefile)
				{
					base.AppendPathString(pInfoData->treeconflict_basefile);
					bConflictData = true;
				}
				if (pInfoData->treeconflict_myfile)
				{
					mine.AppendPathString(pInfoData->treeconflict_myfile);
					bConflictData = true;
				}
				else
				{
					mine = merge;
				}
				if (bConflictData)
					bRet = !!CAppUtils::StartExtMerge(CAppUtils::MergeFlags().AlternativeTool(bAlternativeTool),
														base, theirs, mine, merge);
			}
			else if (pInfoData->treeconflict_kind == svn_wc_conflict_kind_tree)
			{
				CString sConflictAction;
				CString sConflictReason;
				CString sResolveTheirs;
				CString sResolveMine;
				CTSVNPath treeConflictPath = CTSVNPath(pInfoData->treeconflict_path);
				CString sItemName = treeConflictPath.GetUIFileOrDirectoryName();
				
				if (pInfoData->treeconflict_nodekind == svn_node_file)
				{
					switch (pInfoData->treeconflict_operation)
					{
					default:
					case svn_wc_operation_none:
					case svn_wc_operation_update:
						switch (pInfoData->treeconflict_action)
						{
						default:
						case svn_wc_conflict_action_edit:
							sConflictAction.Format(IDS_TREECONFLICT_FILEUPDATEEDIT, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);
							break;
						case svn_wc_conflict_action_add:
							sConflictAction.Format(IDS_TREECONFLICT_FILEUPDATEADD, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);
							break;
						case svn_wc_conflict_action_delete:
							sConflictAction.Format(IDS_TREECONFLICT_FILEUPDATEDELETE, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEFILE);
							break;
						}
						break;
					case svn_wc_operation_switch:
						switch (pInfoData->treeconflict_action)
						{
						default:
						case svn_wc_conflict_action_edit:
							sConflictAction.Format(IDS_TREECONFLICT_FILESWITCHEDIT, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);
							break;
						case svn_wc_conflict_action_add:
							sConflictAction.Format(IDS_TREECONFLICT_FILESWITCHADD, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);
							break;
						case svn_wc_conflict_action_delete:
							sConflictAction.Format(IDS_TREECONFLICT_FILESWITCHDELETE, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEFILE);
							break;
						}
						break;
					case svn_wc_operation_merge:
						switch (pInfoData->treeconflict_action)
						{
						default:
						case svn_wc_conflict_action_edit:
							sConflictAction.Format(IDS_TREECONFLICT_FILEMERGEEDIT, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);
							break;
						case svn_wc_conflict_action_add:
							sConflictAction.Format(IDS_TREECONFLICT_FILEMERGEADD, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);
							break;
						case svn_wc_conflict_action_delete:
							sConflictAction.Format(IDS_TREECONFLICT_FILEMERGEDELETE, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEFILE);
							break;
						}
						break;
					}
				}
				else //if (pInfoData->treeconflict_nodekind == svn_node_dir)
				{
					switch (pInfoData->treeconflict_operation)
					{
					default:
					case svn_wc_operation_none:
					case svn_wc_operation_update:
						switch (pInfoData->treeconflict_action)
						{
						default:
						case svn_wc_conflict_action_edit:
							sConflictAction.Format(IDS_TREECONFLICT_DIRUPDATEEDIT, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);
							break;
						case svn_wc_conflict_action_add:
							sConflictAction.Format(IDS_TREECONFLICT_DIRUPDATEADD, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);
							break;
						case svn_wc_conflict_action_delete:
							sConflictAction.Format(IDS_TREECONFLICT_DIRUPDATEDELETE, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEDIR);
							break;
						}
						break;
					case svn_wc_operation_switch:
						switch (pInfoData->treeconflict_action)
						{
						default:
						case svn_wc_conflict_action_edit:
							sConflictAction.Format(IDS_TREECONFLICT_DIRSWITCHEDIT, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);
							break;
						case svn_wc_conflict_action_add:
							sConflictAction.Format(IDS_TREECONFLICT_DIRSWITCHADD, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);
							break;
						case svn_wc_conflict_action_delete:
							sConflictAction.Format(IDS_TREECONFLICT_DIRSWITCHDELETE, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEDIR);
							break;
						}
						break;
					case svn_wc_operation_merge:
						switch (pInfoData->treeconflict_action)
						{
						default:
						case svn_wc_conflict_action_edit:
							sConflictAction.Format(IDS_TREECONFLICT_DIRMERGEEDIT, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);
							break;
						case svn_wc_conflict_action_add:
							sConflictAction.Format(IDS_TREECONFLICT_DIRMERGEADD, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);
							break;
						case svn_wc_conflict_action_delete:
							sConflictAction.Format(IDS_TREECONFLICT_DIRMERGEDELETE, (LPCTSTR)sItemName);
							sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEDIR);
							break;
						}
						break;
					}
				}

				UINT uReasonID = 0;
				switch (pInfoData->treeconflict_reason)
				{ 
				case svn_wc_conflict_reason_edited:
					uReasonID = IDS_TREECONFLICT_REASON_EDITED;
					sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_KEEPLOCALDIR : IDS_TREECONFLICT_RESOLVE_KEEPLOCALFILE);
					break;
				case svn_wc_conflict_reason_obstructed:
					uReasonID = IDS_TREECONFLICT_REASON_OBSTRUCTED;
					sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_KEEPLOCALDIR : IDS_TREECONFLICT_RESOLVE_KEEPLOCALFILE);
					break;
				case svn_wc_conflict_reason_deleted:
					uReasonID = IDS_TREECONFLICT_REASON_DELETED;
					sResolveMine.LoadString(IDS_TREECONFLICT_RESOLVE_MARKASRESOLVED);
					break;
				case svn_wc_conflict_reason_added:
					uReasonID = IDS_TREECONFLICT_REASON_ADDED;
					sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_KEEPLOCALDIR : IDS_TREECONFLICT_RESOLVE_KEEPLOCALFILE);
					break;
				case svn_wc_conflict_reason_missing:
					uReasonID = IDS_TREECONFLICT_REASON_MISSING;
					sResolveMine.LoadString(IDS_TREECONFLICT_RESOLVE_MARKASRESOLVED);
					break;
				case svn_wc_conflict_reason_unversioned:
					uReasonID = IDS_TREECONFLICT_REASON_UNVERSIONED;
					sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_KEEPLOCALDIR : IDS_TREECONFLICT_RESOLVE_KEEPLOCALFILE);
					break;
				}
				sConflictReason.Format(uReasonID, (LPCTSTR)sConflictAction);

				CTreeConflictEditorDlg dlg;
				dlg.SetConflictInfoText(sConflictReason);
				dlg.SetResolveTexts(sResolveTheirs, sResolveMine);
				dlg.SetPath(treeConflictPath);
				dlg.SetConflictSources(stat.status->tree_conflict->src_left_version, stat.status->tree_conflict->src_right_version);
				dlg.SetConflictReason(pInfoData->treeconflict_reason);
				dlg.SetConflictAction(pInfoData->treeconflict_action);
				INT_PTR dlgRet = dlg.DoModal();
				bRet = (dlgRet != IDCANCEL);
			}
		}
	}

	return bRet;
}
Exemplo n.º 7
0
bool PasteCopyCommand::Execute()
{
	CString sDroppath = parser.GetVal(_T("droptarget"));
	CTSVNPath dropPath(sDroppath);
	ProjectProperties props;
	props.ReadProps(dropPath);
	if (dropPath.IsAdminDir())
		return FALSE;
	SVN svn;
	SVNStatus status;
	unsigned long count = 0;
	CString sNewName;
	pathList.RemoveAdminPaths();
	CProgressDlg progress;
	progress.SetTitle(IDS_PROC_COPYING);
	progress.SetAnimation(IDR_MOVEANI);
	progress.SetTime(true);
	progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
	for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
	{
		const CTSVNPath& sourcePath = pathList[nPath];

		CTSVNPath fullDropPath = dropPath;
		if (sNewName.IsEmpty())
			fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName());
		else
			fullDropPath.AppendPathString(sNewName);

		// Check for a drop-on-to-ourselves
		if (sourcePath.IsEquivalentTo(fullDropPath))
		{
			// Offer a rename
			progress.Stop();
			CRenameDlg dlg;
			dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName());
			if (dlg.DoModal() != IDOK)
			{
				return FALSE;
			}
			// rebuild the progress dialog
			progress.EnsureValid();
			progress.SetTitle(IDS_PROC_COPYING);
			progress.SetAnimation(IDR_MOVEANI);
			progress.SetTime(true);
			progress.SetProgress(count, pathList.GetCount());
			progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
			// Rebuild the destination path, with the new name
			fullDropPath.SetFromUnknown(sDroppath);
			fullDropPath.AppendPathString(dlg.m_name);
		}

		svn_wc_status_kind s = status.GetAllStatus(sourcePath);
		if ((s == svn_wc_status_none)||(s == svn_wc_status_unversioned)||(s == svn_wc_status_ignored))
		{
			// source file is unversioned: move the file to the target, then add it
			CopyFile(sourcePath.GetWinPath(), fullDropPath.GetWinPath(), FALSE);
			if (!svn.Add(CTSVNPathList(fullDropPath), &props, svn_depth_infinity, true, false, true))
			{
				TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
				CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
				return FALSE;		//get out of here
			}
			else
				CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
		}
		else
		{
			if (!svn.Copy(CTSVNPathList(sourcePath), fullDropPath, SVNRev::REV_WC, SVNRev()))
			{
				TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
				CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
				return FALSE;		//get out of here
			}
			else
				CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
		}
		count++;
		if (progress.IsValid())
		{
			progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath());
			progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath());
			progress.SetProgress(count, pathList.GetCount());
		}
		if ((progress.IsValid())&&(progress.HasUserCancelled()))
		{
			CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
			return false;
		}
	}
	return true;
}