In Git, after merging some files, I want to accept all "theirs" that are left in the merge. How do I do that?

Viewed 170

Once I merged some files, how do I accept all the files that are still unmerged (either ours or theirs)?

I tried

git checkout --theirs Project\folder\*.json

But that did not seem to do anything.


This is different than existing questions, because I only want to accept the remaining files. Not all files (which is usually the question that's asked).

3 Answers

To solve this, you can create a PowerShell script that gets all files inside the folder you want to execute the Git command, and iterate through all files running the Git command on each of them.

Here is some code I whipped up. Mind you, I did not test the code with the Git command, although it should work as is. Save the code above with a name of your choosing, for example: "AutoMergeMyFiles.ps1".

To execute it, you need to go to a PowerShell command window, and paste the path of this script file, following the parameters.

It should look like this:

C:\Users\YourName\Desktop\AutoMergeMyFiles.ps1 "folderpath of the files to be merged" "operation (ours / theirs)" and finally the file filter (eg: *.json)

Example: C:\Users\YourName\Desktop\AutoMergeMyFiles.ps1 "C:\GitFiles\MyProject" theirs *.json

param (
    [parameter(Mandatory = $true)] [ValidateScript({
            if ( -Not ($_ | Test-Path) ) {
                throw "File or folder does not exist"
            }
            return $true
        })]
    [string]$mergePath,

    [parameter(Mandatory = $true)] [ValidateSet("ours", "theirs")]
    [string]$operation,

    [parameter(Mandatory = $false)]
    [string]$filter
)

$correctOperation = ""

if ($operation.ToString().Contains("ours") ) {
    $correctOperation = "--ours"
}
elseif ($operation.ToString().Contains("theirs")) {
    $correctOperation = "--theirs"
}

# Get-ChildItem -Path $mergePath -File -Recurse -ErrorAction SilentlyContinue -Force | Select-Object -ExpandProperty FullName
# Get-ChildItem -Path $mergePath -Recurse -ErrorAction SilentlyContinue -Force
$files = Get-ChildItem -Path $mergePath -File -Recurse -ErrorAction SilentlyContinue -Force | Select-Object -ExpandProperty FullName
if ($filter.Length -gt 0) {
    $files = Get-ChildItem -Path $mergePath -Filter $filter -File -Recurse -ErrorAction SilentlyContinue -Force | Select-Object -ExpandProperty FullName
}

foreach ($file in $files) {
    # Write-Output "git checkout $($correctOperation) $($file)"
    git checkout $correctOperation $file
    Start-Sleep -Milliseconds 150
}

Write-Output "Finished merging the files!"

If you just want a list of the files you haven't already resolved, git ls-files -m, and if you want to take the the incoming-branch version of those files without any automerge at all, like a checkout --theirs, the most efficient will be

git ls-files -u | sed -n 's,3\t,0\t,p' | git update-index --index-info
git checkout-index -af

That's “list all unresolved index entries. Select the "theirs" entries as resolved, update the selected index entries, and now update any out-of-date work tree copies“.

If you want merge some files manually and afterwards take the rest from --theirs, do your merge and stage all merged files via

git add path/to/merged.file

Once done with manual merging, take all the rest from --theirs:

git checkout --theirs .

(if you want all files/folders remaining)

git checkout --theirs directory_name/*

(if you want specific folders)

Now continue like any other merge.

Related