0

I have an unusual git question, hoping someone else has done this before and can provide insight...

I'm working on workflow to add files to an existing git project. Through a series of automated steps, I was hoping to create a branch that is completely empty, introduce new files, commit those files to the remote branch, then have the user manually merge the new files so that the new changes don't automatically overwrite/damage anything in the existing project.

I've tried git checkout --orphan, which doesn't do what I want b/c it just creates a "new" history that, when merged, replaces the existing branch's contents. You can't merge these the way you would normally merge changes.

I've also tried doing a normal git checkout -b emptybranch, then manually deleting all of the files and introducing the new files. The problem with this case is that I don't want existing files to be deleted on merge - I only want new files to be included into the new project, or conflicts to be made visible for the project owner to merge themselves.

What I want is the addition/merge of new files without deleting anything existing from the existing branch (and the new branch only contains the new files, nothing else from the existing branch). Any assistance would be greatly appreciated.

Andrew Trice
  • 701
  • 5
  • 8
  • 1
    On the second example you tried (creating branch, removing files, adding your files), when you try to merge this branch, it will delete all the files from the other branch so it won't work. What I'm wondering (cause it's not clear so far) is why don't you try adding the files on another branch (like the second example... but without removing the original files) and then merge them into the other branch? Knowing why you don't try that will help us understand what you actually want. – eftshift0 Jun 14 '17 at 16:49
  • I'm not sure how feasible this is, but I suppose you could try your manual approach and do a "delete commit" so all the delete operation is kept within a single commit, and then, rather than **merging** your newbranch to your oldbranch (thus also merging the delete), you could cherry pick your commits which *add* files only. I'm not sure why you want to do this, though - why do you need an empty branch? – Mike Jun 14 '17 at 16:49
  • The workflow is introducing new files into the project. The reason I don't want old files in there is purely to keep the new changes clean and very, very obvious what has changed in the project structure. Would it work if I didn't delete the existing files... yes, but then it's not nearly as clear what changes were introduced by the automation process. – Andrew Trice Jun 14 '17 at 17:01
  • Git diff will show you exactly what has changed and very clearly. If you delete all files in the same commit that you add new ones, then you **will** pollute the commit and your diff will be useless as every file will show a change. – Mike Jun 14 '17 at 17:02

1 Answers1

0

TL;DR executive summary

I think you do want git checkout --orphan, but you want it followed by git rm -r . (and perhaps also rm -rf of any untracked files this leaves behind).

Description

I've tried git checkout --orphan, which doesn't do what I want b/c it just creates a "new" history that, when merged, replaces the existing branch's contents.

That's not quite right. What --orphan does is set things up so that the next commit on the now-current branch is itself a root commit. Using --orphan is otherwise the same as using -b, i.e., the index remains full of whatever it has at the moment. The work-tree is similarly undisturbed.

If you then also empty out the index (git rm -r . at the top level), and optionally clean out the work-tree as well (if there are any remaining untracked files), then from this point on, only new files you git add from the work-tree will be in the next commit. (You might want to commit just a README-ish file first, as is often done in the initial root commit of a new, totally-empty repository, for the same reasons that people make such a commit in a new repository.)

Later, if and when you go to git merge this branch, Git now (as of 2.9) rejects the attempt unless you add --allow-unrelated-histories. This is because there is no merge base between the orphan branch and the other branches in your repository. Adding --allow-unrelated-histories tells Git to use a synthetic empty commit (actually, the empty tree) as the merge base. Hence during the merge, all files in both branch tips are viewed as newly-added, and if any two files are identified (i.e., have the same path name in both tip commits), you will get an add/add conflict on them and be forced to resolve this manually. Given your problem description, it sounds like this is what you wnat.

torek
  • 448,244
  • 59
  • 642
  • 775
  • I'll test this out. I assume `--alow-unrelated-histories` is only available via git command line? GitHub currently provides a sub-optimal user experience for this process by displaying this message: `There isn’t anything to compare. master and orphan-test are entirely different commit histories.` – Andrew Trice Jun 14 '17 at 18:14
  • It seems so. (I'm no GitHub expert, I'm more of a casual user of GitHub itself, and its web browser interface.) – torek Jun 14 '17 at 18:16