sourcegit-scm/sourcegit

开着pull的rebase选项,然后merge的时候出现问题

Closed this issue · 15 comments

Image

猜测是开着这个选项选择merge的时候造成了冲突,然后解决冲突后部分文件丢失。

用的是在远程分支上右键选择merge,然后解决冲突后就乱了。

如果是按图上选的Do nothing的话,有冲突不会merge的,丢了变更的话那就是解决冲突的时候被放弃了。如果选了stash的话,它应该在你的贮藏列表里

Pull这个选项,仅在Pull命令执行时起作用,不会修改任何仓库设置。在远程右键merge时与pull操作无关。为单独的git merge命令调用。

我想知道【然后解决冲突后就乱了】指的是什么情况,比如,是否可以提供一个可以复现的Demo仓库及操作指南?

在工程仓库里遇到的问题,不方便提供案例。我操作了两遍都遇到了问题,具体问题是某些新加的CS文件丢失了,合并后根本不存在。
我回退了操作用tortoisegit合并了一遍,完全正确,没有丢失文件。当前没有环境了,我也不确定具体问题出在哪个环节了。

+1. 开启 use rebase instead of merge 总是有冲突。命令行直接 git pull 没问题。.gitconfig 部分如下,猜测是 rebase.backend 的问题。

[pull]
    rebase = true
[rebase]
    autoStash = false
    updateRefs = false
    backend = merge

+1. 开启 use rebase instead of merge 总是有冲突。命令行直接 git pull 没问题。.gitconfig 部分如下,猜测是 rebase.backend 的问题。

[pull]
rebase = true
[rebase]
autoStash = false
updateRefs = false
backend = merge

你们两个的问题不是一个,@owllyi 说的是

用的是在远程分支上右键选择merge,然后解决冲突后就乱了。

如果pull操作已经产生了冲突,应当直接在LOCAL CHANGES页面解决然后CONTINUE,或直接ABORT合并操作。

@xgugeng 你在pull操作的同时,有没有开启Fetch all branches选项?如果没有,实际上的操作与你命令行操作基本一致:

public class Pull : Command
{
    public Pull(string repo, string remote, string branch, bool useRebase, bool noTags, Action<string> outputHandler)
    {
        _outputHandler = outputHandler;
        WorkingDirectory = repo;
        Context = repo;
        TraitErrorAsOutput = true;
        SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
        Args = "pull --verbose --progress ";

        if (useRebase)
            Args += "--rebase=true ";

        if (noTags)
            Args += "--no-tags ";

        Args += $"{remote} {branch}";
    }

    protected override void OnReadline(string line)
    {
        _outputHandler?.Invoke(line);
    }

    private readonly Action<string> _outputHandler;
}

如果开启了,SourceGit会使用组合命令

if (FetchAllBranches)
{
    SetProgressDescription($"Fetching remote: {_selectedRemote.Name}...");
    rs = new Commands.Fetch(
        _repo.FullPath,
        _selectedRemote.Name,
        NoTags,
        false,
        SetProgressDescription).Exec();

    if (!rs)
    {
        CallUIThread(() => _repo.SetWatcherEnabled(true));
        return false;
    }

    _repo.MarkFetched();

    // Use merge/rebase instead of pull as fetch is done manually.
    if (UseRebase)
    {
        SetProgressDescription($"Rebase {_current.Name} on {_selectedBranch.FriendlyName} ...");
        rs = new Commands.Rebase(_repo.FullPath, _selectedBranch.FriendlyName, false).Exec();
    }
    else
    {
        SetProgressDescription($"Merge {_selectedBranch.FriendlyName} into {_current.Name} ...");
        rs = new Commands.Merge(_repo.FullPath, _selectedBranch.FriendlyName, "", SetProgressDescription).Exec();
    }
}

谢谢 @love-lingerFetch all branches 的确是开启的。

@xgugeng 如果开启中,基本上就可以缩小范围到 rs = new Commands.Rebase(_repo.FullPath, _selectedBranch.FriendlyName, false).Exec(); 这句代码的问题,后面我仔细看一下

我的问题是merge的时候遇到冲突,手工解决完所有冲突之后,验证代码,发现部分代码丢失,没有正确merge。只能选择reset回退。

还有个问题,merge冲突的时候解决完冲突自动就提交了,能手动提交吗。此外有冲突的时候commit msg里没有包含冲突文件名,和小乌龟、fork的表现不一致,希望能保留冲突文件名备查。

我也开启了FetchAllBranches这个选项

我的问题是merge的时候遇到冲突,手工解决完所有冲突之后,验证代码,发现部分代码丢失,没有正确merge。只能选择reset回退。

关于 Local Changes 选项:

  • 选择Do Nothing时,SourceGit不会做任何处理,由git决定
  • 选择Stash & Reapply时,SourceGit会自动创建一个Stash包含所有的本地变更,该操作会清理当前的worktree为干净的状态,为合并做准备。并在合并完成后,自动从stash中恢复贮藏的变更。如果中途出问题,不会自动恢复,但STASHES页面中保留了该贮藏
  • 选择Discard时,所有的本地变更都会被丢弃

完成本地变更处理后,将根据选项执行以下命令

  • 如果选择了 Fetch all branches,先执行git fetch --progress --verbose <remote> 再执行:
    • 如果 Use rebase instead of merge 启用,执行 git rebase <remote_branch>
    • 否则执行 git merge --progress <remote_branch>
  • 如果没有启用 Fetch all branches,直接执行 git pull --verbose --progress [--rebase=true] <remote> <branch>

还有个问题,merge冲突的时候解决完冲突自动就提交了,能手动提交吗。

可以的,你可以点击CONTINUE后面的下拉框,选COMMIT (Edit)按钮。你也可以直接修改提交信息,再点击CONTINUE(该操作会修改最终的提交信息)

此外有冲突的时候commit msg里没有包含冲突文件名,和小乌龟、fork的表现不一致,希望能保留冲突文件名备查。

该功能是有的,我不清楚为什么你那里没有自动填入.git/MERGE_MSG文件中的内容。

Image

感谢回复,我回头再试试看,遇到问题再观察下是哪里的问题。

同时开着Pull界面里的Fetch all branches和Use rebase instead of merge,我单独使用merge功能的时候会用rebase代替merge么?

不会,Pull操作界面中的设备仅对其自己有效(因为本身pull = fetch + merge/rebase)。其他地方(比如分支,提交等)右键中merge与rebase都是分开的。