Пример #1
0
bool CGitStatus::GetRepoRootInternal(const wstring& path, wstring& repoRoot_out, git_buf &buf, git_repository *&repo)
{
	// This is temporary.
	CMutexLock mutexLock(&m_mutex);

	SecureZeroMemory(&buf, sizeof(git_buf));
	wstring_convert<codecvt_utf8<wchar_t>> converter;
	string cpath = converter.to_bytes(path);

	if (git_repository_discover(&buf, cpath.c_str(), 0, NULL))
	{
		Logger::LogWarning(_T("Unable to find git repository"));
		return false;
	}

	if (git_repository_open(&repo, buf.ptr))
	{
		Logger::LogError(_T("Unable to open repository"));
		git_buf_free(&buf);
		return false;
	}

	const char* workDir = git_repository_workdir(repo);
	if (workDir == nullptr)
	{
		Logger::LogWarning(_T("No working directory. Probably bare repository."));
		git_buf_free(&buf);
		return false;
	}
	repoRoot_out = MyUtils::NormalizePath(converter.from_bytes(workDir));
	
	return true;
}
Пример #2
0
PyObject *
discover_repository(PyObject *self, PyObject *args)
{
    git_buf repo_path = {NULL};
    const char *path;
    PyObject *py_repo_path;
    int across_fs = 0;
    const char *ceiling_dirs = NULL;
    int err;

    if (!PyArg_ParseTuple(args, "s|Is", &path, &across_fs, &ceiling_dirs))
        return NULL;

    memset(&repo_path, 0, sizeof(git_buf));
    err = git_repository_discover(&repo_path, path, across_fs, ceiling_dirs);
    if (err == GIT_ENOTFOUND)
        Py_RETURN_NONE;
    if (err < 0)
        return Error_set_str(err, path);

    py_repo_path = to_path(repo_path.ptr);
    git_buf_dispose(&repo_path);

    return py_repo_path;
};
Пример #3
0
static void ensure_repository_discover(const char *start_path,
                                       const char *ceiling_dirs,
                                       const char *expected_path)
{
	char found_path[GIT_PATH_MAX];
	cl_git_pass(git_repository_discover(found_path, sizeof(found_path), start_path, 0, ceiling_dirs));
	//across_fs is always 0 as we can't automate the filesystem change tests
	cl_assert_equal_s(found_path, expected_path);
}
Пример #4
0
int
main(int argc, char **argv)
{
	git_buf pathbuf;
	const char *path;
	const git_error *err;
	git_repository *repo;
	struct tag_filter_struct filter;
	
	path = NULL;
	if(argc == 2)
	{
		path = argv[1];
	}
	else if(argc != 1)
	{
		usage(argv[0]);
		exit(EXIT_FAILURE);
	}
	if(!path)
	{
		path = getenv("GIT_DIR");
	}
	memset(&pathbuf, 0, sizeof(pathbuf));
	if(!path)
	{
		if(git_repository_discover(&pathbuf, ".", 0, "/"))
		{
			err = giterr_last();
			fprintf(stderr, "%s: %s\n", path, err->message);
			exit(EXIT_FAILURE);
		}
		path = pathbuf.ptr;
	}
	if(git_repository_open(&repo, path))
	{
		err = giterr_last();
		fprintf(stderr, "%s: %s\n", path, err->message);
		exit(EXIT_FAILURE);
	}
	/* Only available in HEAD:
	git_tag_foreach(repo, tag_callback, NULL);
	 */
	filter.data = NULL;
	filter.cb = tag_callback;
	filter.repo = repo;
	git_reference_foreach(repo, ref_callback, &filter);
	git_repository_free(repo);
	git_buf_free(&pathbuf);
	return 0;
}
Пример #5
0
PyObject *
discover_repository(PyObject *self, PyObject *args)
{
    const char *path;
    int across_fs = 0;
    const char *ceiling_dirs = NULL;
    char repo_path[MAXPATHLEN];
    int err;

    if (!PyArg_ParseTuple(args, "s|Is", &path, &across_fs, &ceiling_dirs))
        return NULL;

    err = git_repository_discover(repo_path, sizeof(repo_path),
            path, across_fs, ceiling_dirs);
    if (err < 0)
        return Error_set_str(err, path);

    return to_path(repo_path);
};
Пример #6
0
git_repository* get_git_repository() {
	if (repository == NULL) {
		char discovered_path[PATH_MAX];
		char *repository_path = getenv(GIT_DIR_ENVIRONMENT);

		if (repository_path == NULL) {
			if (git_repository_discover(discovered_path, sizeof(discovered_path), "", 0, getenv(GIT_CEILING_DIRECTORIES_ENVIRONMENT)) < GIT_OK) {
				libgit_error();
			}

			repository_path = discovered_path;
		}

		if (git_repository_open(&repository, repository_path) < GIT_OK) {
			libgit_error();
		}
	}

	return repository;
}
Пример #7
0
/**
 * Find repository base path for given path
 *
 * @param path A character vector specifying the path to a file or folder
 * @return R_NilValue if repository cannot be found or
 * a character vector of length one with path to repository's git dir
 * e.g. /path/to/my/repo/.git
 */
SEXP git2r_repository_discover(SEXP path)
{
    int err;
    SEXP result = R_NilValue;
    git_buf buf = GIT_BUF_INIT;

    if (git2r_arg_check_string(path))
        git2r_error(git2r_err_string_arg, __func__, "path");

    /* note that across_fs (arg #3) is set to 0 so this will stop when
     * a filesystem device change is detected while exploring parent
     * directories */
    err = git_repository_discover(&buf,
                                  CHAR(STRING_ELT(path, 0)),
                                  0,
                                  /* const char *ceiling_dirs */ NULL);
    if (GIT_OK != err) {
        /* NB just return R_NilValue if we can't discover the repo */
        if (GIT_ENOTFOUND == err)
            err = GIT_OK;
        goto cleanup;
    }

    PROTECT(result = allocVector(STRSXP, 1));
    SET_STRING_ELT(result, 0, mkChar(buf.ptr));

cleanup:
    git_buf_free(&buf);

    if (R_NilValue != result)
        UNPROTECT(1);

    if (GIT_OK != err)
        git2r_error(git2r_err_from_libgit2, __func__, giterr_last()->message);

    return result;
}
Пример #8
0
void test_repo_discover__0(void)
{
   // test discover
	git_repository *repo;
	git_buf ceiling_dirs_buf = GIT_BUF_INIT;
	const char *ceiling_dirs;
	char repository_path[GIT_PATH_MAX];
	char sub_repository_path[GIT_PATH_MAX];
	char found_path[GIT_PATH_MAX];
	const mode_t mode = 0777;

	git_futils_mkdir_r(DISCOVER_FOLDER, NULL, mode);
	append_ceiling_dir(&ceiling_dirs_buf, TEMP_REPO_FOLDER);
	ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf);

	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(repository_path, sizeof(repository_path), DISCOVER_FOLDER, 0, ceiling_dirs));

	cl_git_pass(git_repository_init(&repo, DISCOVER_FOLDER, 1));
	cl_git_pass(git_repository_discover(repository_path, sizeof(repository_path), DISCOVER_FOLDER, 0, ceiling_dirs));
	git_repository_free(repo);

	cl_git_pass(git_repository_init(&repo, SUB_REPOSITORY_FOLDER, 0));
	cl_git_pass(git_futils_mkdir_r(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, NULL, mode));
	cl_git_pass(git_repository_discover(sub_repository_path, sizeof(sub_repository_path), SUB_REPOSITORY_FOLDER, 0, ceiling_dirs));

	cl_git_pass(git_futils_mkdir_r(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, NULL, mode));
	ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB, ceiling_dirs, sub_repository_path);
	ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB_SUB, ceiling_dirs, sub_repository_path);
	ensure_repository_discover(SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, ceiling_dirs, sub_repository_path);

	cl_git_pass(git_futils_mkdir_r(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, NULL, mode));
	write_file(REPOSITORY_ALTERNATE_FOLDER "/" DOT_GIT, "gitdir: ../" SUB_REPOSITORY_FOLDER_NAME "/" DOT_GIT);
	write_file(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB "/" DOT_GIT, "gitdir: ../../../" SUB_REPOSITORY_FOLDER_NAME "/" DOT_GIT);
	write_file(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB "/" DOT_GIT, "gitdir: ../../../../");
	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER, ceiling_dirs, sub_repository_path);
	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB, ceiling_dirs, sub_repository_path);
	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB, ceiling_dirs, sub_repository_path);
	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, ceiling_dirs, repository_path);

	cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER1, NULL, mode));
	write_file(ALTERNATE_MALFORMED_FOLDER1 "/" DOT_GIT, "Anything but not gitdir:");
	cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER2, NULL, mode));
	write_file(ALTERNATE_MALFORMED_FOLDER2 "/" DOT_GIT, "gitdir:");
	cl_git_pass(git_futils_mkdir_r(ALTERNATE_MALFORMED_FOLDER3, NULL, mode));
	write_file(ALTERNATE_MALFORMED_FOLDER3 "/" DOT_GIT, "gitdir: \n\n\n");
	cl_git_pass(git_futils_mkdir_r(ALTERNATE_NOT_FOUND_FOLDER, NULL, mode));
	write_file(ALTERNATE_NOT_FOUND_FOLDER "/" DOT_GIT, "gitdir: a_repository_that_surely_does_not_exist");
	cl_git_fail(git_repository_discover(found_path, sizeof(found_path), ALTERNATE_MALFORMED_FOLDER1, 0, ceiling_dirs));
	cl_git_fail(git_repository_discover(found_path, sizeof(found_path), ALTERNATE_MALFORMED_FOLDER2, 0, ceiling_dirs));
	cl_git_fail(git_repository_discover(found_path, sizeof(found_path), ALTERNATE_MALFORMED_FOLDER3, 0, ceiling_dirs));
	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(found_path, sizeof(found_path), ALTERNATE_NOT_FOUND_FOLDER, 0, ceiling_dirs));

	append_ceiling_dir(&ceiling_dirs_buf, SUB_REPOSITORY_FOLDER);
	ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf);

	//this must pass as ceiling_directories cannot predent the current
	//working directory to be checked
	cl_git_pass(git_repository_discover(found_path, sizeof(found_path), SUB_REPOSITORY_FOLDER, 0, ceiling_dirs));
	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(found_path, sizeof(found_path), SUB_REPOSITORY_FOLDER_SUB, 0, ceiling_dirs));
	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(found_path, sizeof(found_path), SUB_REPOSITORY_FOLDER_SUB_SUB, 0, ceiling_dirs));
	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_discover(found_path, sizeof(found_path), SUB_REPOSITORY_FOLDER_SUB_SUB_SUB, 0, ceiling_dirs));

	//.gitfile redirection should not be affected by ceiling directories
	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER, ceiling_dirs, sub_repository_path);
	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB, ceiling_dirs, sub_repository_path);
	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB, ceiling_dirs, sub_repository_path);
	ensure_repository_discover(REPOSITORY_ALTERNATE_FOLDER_SUB_SUB_SUB, ceiling_dirs, repository_path);

	cl_git_pass(git_futils_rmdir_r(TEMP_REPO_FOLDER, NULL, GIT_RMDIR_REMOVE_FILES));
	git_repository_free(repo);
	git_buf_free(&ceiling_dirs_buf);
}
Пример #9
0
LRESULT CMainWindow::DoCommand(int id, LPARAM lParam)
{
    switch (id)
    {
    case ID_FILE_OPEN:
        {
            if (OpenDialog())
            {
                picWindow1.SetPic(leftpicpath, L"", true);
                picWindow2.SetPic(rightpicpath, L"", false);
                if (bOverlap)
                {
                    picWindow1.SetSecondPic(picWindow2.GetPic(), rightpictitle, rightpicpath);
                }
                else
                {
                    picWindow1.SetSecondPic();
                }
                RECT rect;
                GetClientRect(*this, &rect);
                PositionChildren(&rect);
                picWindow1.FitImageInWindow();
                picWindow2.FitImageInWindow();
            }
        }
        break;
    case ID_VIEW_IMAGEINFO:
        {
            bShowInfo = !bShowInfo;
            HMENU hMenu = GetMenu(*this);
            UINT uCheck = MF_BYCOMMAND;
            uCheck |= bShowInfo ? MF_CHECKED : MF_UNCHECKED;
            CheckMenuItem(hMenu, ID_VIEW_IMAGEINFO, uCheck);

            picWindow1.ShowInfo(bShowInfo);
            picWindow2.ShowInfo(bShowInfo);
            picWindow3.ShowInfo(bShowInfo);

            // change the state of the toolbar button
            TBBUTTONINFO tbi;
            tbi.cbSize = sizeof(TBBUTTONINFO);
            tbi.dwMask = TBIF_STATE;
            tbi.fsState = bShowInfo ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_IMAGEINFO, (LPARAM)&tbi);
        }
        break;
    case ID_VIEW_OVERLAPIMAGES:
        {
            bOverlap = !bOverlap;
            HMENU hMenu = GetMenu(*this);
            UINT uCheck = MF_BYCOMMAND;
            uCheck |= bOverlap ? MF_CHECKED : MF_UNCHECKED;
            CheckMenuItem(hMenu, ID_VIEW_OVERLAPIMAGES, uCheck);
            uCheck |= ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? MF_CHECKED : MF_UNCHECKED;
            CheckMenuItem(hMenu, ID_VIEW_BLENDALPHA, uCheck);
            UINT uEnabled = MF_BYCOMMAND;
            uEnabled |= bOverlap ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
            EnableMenuItem(hMenu, ID_VIEW_BLENDALPHA, uEnabled);

            // change the state of the toolbar button
            TBBUTTONINFO tbi;
            tbi.cbSize = sizeof(TBBUTTONINFO);
            tbi.dwMask = TBIF_STATE;
            tbi.fsState = bOverlap ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_OVERLAPIMAGES, (LPARAM)&tbi);

            tbi.fsState = ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? TBSTATE_CHECKED : 0;
            if (bOverlap)
                tbi.fsState |= TBSTATE_ENABLED;
            else
                tbi.fsState = 0;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_BLENDALPHA, (LPARAM)&tbi);

            if (bOverlap)
                tbi.fsState = 0;
            else
                tbi.fsState = bVertical ? TBSTATE_ENABLED | TBSTATE_CHECKED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_ARRANGEVERTICAL, (LPARAM)&tbi);

            if (bOverlap)
            {
                bLinkedPositions = true;
                picWindow1.LinkPositions(bLinkedPositions);
                picWindow2.LinkPositions(bLinkedPositions);
                tbi.fsState = TBSTATE_CHECKED;
            }
            else
                tbi.fsState = bLinkedPositions ? TBSTATE_ENABLED | TBSTATE_CHECKED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_LINKIMAGESTOGETHER, (LPARAM)&tbi);

            ShowWindow(picWindow2, bOverlap ? SW_HIDE : SW_SHOW);

            if (bOverlap)
            {
                picWindow1.StopTimer();
                picWindow2.StopTimer();
                picWindow1.SetSecondPic(picWindow2.GetPic(), rightpictitle, rightpicpath,
                    picWindow2.GetHPos(), picWindow2.GetVPos());
                picWindow1.SetBlendAlpha(m_BlendType, 0.5f);
            }
            else
            {
                picWindow1.SetSecondPic();
            }
            picWindow1.SetOverlapMode(bOverlap);
            picWindow2.SetOverlapMode(bOverlap);


            RECT rect;
            GetClientRect(*this, &rect);
            PositionChildren(&rect);

            return 0;
        }
        break;
    case ID_VIEW_BLENDALPHA:
        {
            if (m_BlendType == CPicWindow::BLEND_ALPHA)
                m_BlendType = CPicWindow::BLEND_XOR;
            else
                m_BlendType = CPicWindow::BLEND_ALPHA;

            HMENU hMenu = GetMenu(*this);
            UINT uCheck = MF_BYCOMMAND;
            uCheck |= ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? MF_CHECKED : MF_UNCHECKED;
            CheckMenuItem(hMenu, ID_VIEW_BLENDALPHA, uCheck);
            UINT uEnabled = MF_BYCOMMAND;
            uEnabled |= bOverlap ? MF_ENABLED : MF_DISABLED | MF_GRAYED;
            EnableMenuItem(hMenu, ID_VIEW_BLENDALPHA, uEnabled);

            // change the state of the toolbar button
            TBBUTTONINFO tbi;
            tbi.cbSize = sizeof(TBBUTTONINFO);
            tbi.dwMask = TBIF_STATE;
            tbi.fsState = ((m_BlendType == CPicWindow::BLEND_ALPHA) && bOverlap) ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_BLENDALPHA, (LPARAM)&tbi);
            picWindow1.SetBlendAlpha(m_BlendType, picWindow1.GetBlendAlpha());
            PositionChildren();
        }
        break;
    case ID_VIEW_TRANSPARENTCOLOR:
        {
            static COLORREF customColors[16] = {0};
            CHOOSECOLOR ccDlg = { 0 };
            ccDlg.lStructSize = sizeof(ccDlg);
            ccDlg.hwndOwner = m_hwnd;
            ccDlg.rgbResult = transparentColor;
            ccDlg.lpCustColors = customColors;
            ccDlg.Flags = CC_RGBINIT | CC_FULLOPEN;
            if(ChooseColor(&ccDlg))
            {
                transparentColor = ccDlg.rgbResult;
                picWindow1.SetTransparentColor(transparentColor);
                picWindow2.SetTransparentColor(transparentColor);
                picWindow3.SetTransparentColor(transparentColor);
                // The color picker takes the focus and we don't get it back.
                ::SetFocus(picWindow1);
            }
        }
        break;
    case ID_VIEW_FITIMAGEWIDTHS:
        {
            bFitWidths = !bFitWidths;
            picWindow1.FitWidths(bFitWidths);
            picWindow2.FitWidths(bFitWidths);
            picWindow3.FitWidths(bFitWidths);

            HMENU hMenu = GetMenu(*this);
            UINT uCheck = MF_BYCOMMAND;
            uCheck |= bFitWidths ? MF_CHECKED : MF_UNCHECKED;
            CheckMenuItem(hMenu, ID_VIEW_FITIMAGEWIDTHS, uCheck);

            // change the state of the toolbar button
            TBBUTTONINFO tbi;
            tbi.cbSize = sizeof(TBBUTTONINFO);
            tbi.dwMask = TBIF_STATE;
            tbi.fsState = bFitWidths ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_FITIMAGEWIDTHS, (LPARAM)&tbi);
        }
        break;
    case ID_VIEW_FITIMAGEHEIGHTS:
        {
            bFitHeights = !bFitHeights;
            picWindow1.FitHeights(bFitHeights);
            picWindow2.FitHeights(bFitHeights);
            picWindow3.FitHeights(bFitHeights);

            HMENU hMenu = GetMenu(*this);
            UINT uCheck = MF_BYCOMMAND;
            uCheck |= bFitHeights ? MF_CHECKED : MF_UNCHECKED;
            CheckMenuItem(hMenu, ID_VIEW_FITIMAGEHEIGHTS, uCheck);

            // change the state of the toolbar button
            TBBUTTONINFO tbi;
            tbi.cbSize = sizeof(TBBUTTONINFO);
            tbi.dwMask = TBIF_STATE;
            tbi.fsState = bFitHeights ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_FITIMAGEHEIGHTS, (LPARAM)&tbi);
        }
        break;
    case ID_VIEW_LINKIMAGESTOGETHER:
        {
            bLinkedPositions = !bLinkedPositions;
            picWindow1.LinkPositions(bLinkedPositions);
            picWindow2.LinkPositions(bLinkedPositions);
            picWindow3.LinkPositions(bLinkedPositions);

            HMENU hMenu = GetMenu(*this);
            UINT uCheck = MF_BYCOMMAND;
            uCheck |= bLinkedPositions ? MF_CHECKED : MF_UNCHECKED;
            CheckMenuItem(hMenu, ID_VIEW_LINKIMAGESTOGETHER, uCheck);

            // change the state of the toolbar button
            TBBUTTONINFO tbi;
            tbi.cbSize = sizeof(TBBUTTONINFO);
            tbi.dwMask = TBIF_STATE;
            tbi.fsState = bLinkedPositions ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_LINKIMAGESTOGETHER, (LPARAM)&tbi);
        }
        break;
    case ID_VIEW_ALPHA0:
        picWindow1.SetBlendAlpha(m_BlendType, 0.0f);
        break;
    case ID_VIEW_ALPHA255:
        picWindow1.SetBlendAlpha(m_BlendType, 1.0f);
        break;
    case ID_VIEW_ALPHA127:
        picWindow1.SetBlendAlpha(m_BlendType, 0.5f);
        break;
    case ID_VIEW_ALPHATOGGLE:
        picWindow1.ToggleAlpha();
        break;
    case ID_VIEW_FITIMAGESINWINDOW:
        {
            picWindow1.FitImageInWindow();
            picWindow2.FitImageInWindow();
            picWindow3.FitImageInWindow();
        }
        break;
    case ID_VIEW_ORININALSIZE:
        {
            picWindow1.SetZoom(100, false);
            picWindow2.SetZoom(100, false);
            picWindow3.SetZoom(100, false);
            picWindow1.CenterImage();
            picWindow2.CenterImage();
            picWindow3.CenterImage();
        }
        break;
    case ID_VIEW_ZOOMIN:
        {
            picWindow1.Zoom(true, false);
            if ((!(bFitWidths || bFitHeights))&&(!bOverlap))
            {
                picWindow2.Zoom(true, false);
                picWindow3.Zoom(true, false);
            }
        }
        break;
    case ID_VIEW_ZOOMOUT:
        {
            picWindow1.Zoom(false, false);
            if ((!(bFitWidths || bFitHeights))&&(!bOverlap))
            {
                picWindow2.Zoom(false, false);
                picWindow3.Zoom(false, false);
            }
        }
        break;
    case ID_VIEW_ARRANGEVERTICAL:
        {
            bVertical = !bVertical;
            RECT rect;
            GetClientRect(*this, &rect);
            if (bVertical)
            {
                RECT tbRect;
                GetWindowRect(hwndTB, &tbRect);
                LONG tbHeight = tbRect.bottom-tbRect.top-1;
                if (selectionPaths.size() != 3)
                {
                    nSplitterPos = (rect.bottom-rect.top)/2+tbHeight;
                    nSplitterPos2 = 0;
                }
                else
                {
                    nSplitterPos = (rect.bottom-rect.top)/3+tbHeight;
                    nSplitterPos2 = (rect.bottom-rect.top)*2/3+tbHeight;
                }
            }
            else
            {
                if (selectionPaths.size() != 3)
                {
                    nSplitterPos = (rect.right-rect.left)/2;
                    nSplitterPos2 = 0;
                }
                else
                {
                    nSplitterPos = (rect.right-rect.left)/3;
                    nSplitterPos2 = (rect.right-rect.left)*2/3;
                }
            }
            HMENU hMenu = GetMenu(*this);
            UINT uCheck = MF_BYCOMMAND;
            uCheck |= bVertical ? MF_CHECKED : MF_UNCHECKED;
            CheckMenuItem(hMenu, ID_VIEW_ARRANGEVERTICAL, uCheck);
            // change the state of the toolbar button
            TBBUTTONINFO tbi;
            tbi.cbSize = sizeof(TBBUTTONINFO);
            tbi.dwMask = TBIF_STATE;
            tbi.fsState = bVertical ? TBSTATE_CHECKED | TBSTATE_ENABLED : TBSTATE_ENABLED;
            SendMessage(hwndTB, TB_SETBUTTONINFO, ID_VIEW_ARRANGEVERTICAL, (LPARAM)&tbi);

            PositionChildren(&rect);
        }
        break;
    case ID_ABOUT:
        {
            CAboutDlg dlg(*this);
            dlg.DoModal(hInst, IDD_ABOUT, *this);
        }
        break;
    case SELECTBUTTON_ID:
        {
            HWND hSource = (HWND)lParam;
            FileType resolveWith;
            if (picWindow1 == hSource)
                resolveWith = FileTypeMine;
            else if (picWindow2 == hSource)
                resolveWith = FileTypeBase;
            else if (picWindow3 == hSource)
                resolveWith = FileTypeTheirs;
            else
                break;

            if (selectionResult.empty())
            {
                PostQuitMessage(resolveWith);
                break;
            }

            CopyFile(selectionPaths[resolveWith].c_str(), selectionResult.c_str(), FALSE);

            CAutoBuf projectRoot;
            if (git_repository_discover(projectRoot, CUnicodeUtils::GetUTF8(selectionResult.c_str()), FALSE, nullptr) < 0 && strstr(projectRoot->ptr, "/.git/"))
            {
                PostQuitMessage(resolveWith);
                break;
            }

            CAutoRepository repository(projectRoot->ptr);
            if (!repository)
            {
                PostQuitMessage(resolveWith);
                break;
            }

            CStringA subpath = CUnicodeUtils::GetUTF8(selectionResult.c_str()).Mid((int)strlen(git_repository_workdir(repository)));

            CAutoIndex index;
            if (git_repository_index(index.GetPointer(), repository) || (git_index_get_bypath(index, subpath, 1) == nullptr && git_index_get_bypath(index, subpath, 2) == nullptr))
            {
                PostQuitMessage(resolveWith);
                break;
            }

            CString sTemp;
            sTemp.Format(ResString(hResource, IDS_MARKASRESOLVED), (LPCTSTR)CPathUtils::GetFileNameFromPath(selectionResult.c_str()));
            if (MessageBox(m_hwnd, sTemp, L"TortoiseGitMerge", MB_YESNO | MB_ICONQUESTION) != IDYES)
                break;

            CString cmd;
            cmd.Format(L"\"%sTortoiseGitProc.exe\" /command:resolve /path:\"%s\" /closeonend:1 /noquestion /skipcheck /silent", (LPCTSTR)CPathUtils::GetAppDirectory(), selectionResult.c_str());
            if (resolveMsgWnd)
                cmd.AppendFormat(L" /resolvemsghwnd:%I64d /resolvemsgwparam:%I64d /resolvemsglparam:%I64d", (__int64)resolveMsgWnd, (__int64)resolveMsgWParam, (__int64)resolveMsgLParam);

            STARTUPINFO startup = { 0 };
            PROCESS_INFORMATION process = { 0 };
            startup.cb = sizeof(startup);

            if (!CreateProcess(nullptr, cmd.GetBuffer(), nullptr, nullptr, FALSE, CREATE_UNICODE_ENVIRONMENT, nullptr, nullptr, &startup, &process))
            {
                cmd.ReleaseBuffer();
                PostQuitMessage(resolveWith);
                break;
            }
            cmd.ReleaseBuffer();

            AllowSetForegroundWindow(process.dwProcessId);

            CloseHandle(process.hThread);
            CloseHandle(process.hProcess);

            PostQuitMessage(resolveWith);
        }
        break;
    case IDM_EXIT:
        ::PostQuitMessage(0);
        return 0;
        break;
    default:
        break;
    };
    return 1;
}