1

I have folder A_Folder. Inside that folder there is file A_File.html. That folder is in branch_A of my repositroy. I have also a branch_b which has file B_File.html. How can i merge A_File.html and B_File.html together to save final code in A_file.html?

Nikolay Shubenkov
  • 3,133
  • 1
  • 29
  • 31
  • yes, But in my case one of the 2 files is not in the same folder. Shall I make it `A_Folder/A_File.html` instead A_File.html when using that merge algorithm? – Mohamed AbdelAzeem Dec 09 '20 at 17:14

1 Answers1

1

You've used a technical term, merge, in a way it doesn't apply.

You may be thinking of the general (non-Git) verb to merge, meaning to combine. If so, the way to do this is simple: obtain the data from the two files you wish to combine into a single file, and then combine that into a single file.

Git's idea of merging

The Git form of the verb to merge is normally something we apply to entire commits, not to files. That is, we run:

git checkout argument-1
git merge argument-2

The two arguments here, argument-1 and argument-2, identify commits (sometimes via branch names, but the branch names are not important). A commit, in Git, is an entity that holds two things:

  • a snapshot of all files, and
  • some metadata.

The merging process in Git uses the two specified commits to locate a third commit, which also contains a snapshot of all files. The merging process then works on these three inputs.

If you would like to merge three inputs, with the three inputs being files, you can use git merge-file. The merging process that Git applies to three input commits consists in part of running git merge-file on the files from the three commits. (Before this, the merging process must group the files together in the right way, so that the correct three files are merged by each git merge-file; we won't cover that here since you aren't concerned with this part.)

Your kind of merging

In your case, it sounds like you only have two inputs, not three. So Git's merging is not what you are interested in. Hence, you should not use Git to accomplish the merge.

I have folder A_Folder inside that folder there is file A_File.html that folder is inside branch_A in my repo.

Technically, the name branch_A identifies one specific commit. To access this entire commit—making it your current commit—you simply run:

git checkout branch_A

and now all the files that are in the last commit that is on branch_A are in your working tree, available for you to do whatever you want with.

At this point, it could make sense for you to copy A_Folder/A_File.html to some file outside the working tree (e.g., in /tmp or wherever you like on your computer). You will now have all the data from that file available.

I have also branch_b it has file B_File.html

As before, the name branch_b simply identifies one commit, specifically the last commit that is on that branch. To obtain all the files from that commit, you simply run:

git checkout branch_b

You now have, in your working tree, all the files from that commit. You can now copy the contents of B_File.html outside of the working tree, e.g., to /tmp if you like.

Now that you have both file-contents, you can choose which commit(s) and/or branches, if any, in your repository should contain the combined contents. Let's say that the right place to put them is in a new commit on a new branch that is to be grown from the last commit that is currently on branch master. You would achieve this by doing:

git checkout -b newbranch master

which will fill your working tree with the files from the last commit on branch master, create a new branch name newbranch, and set things up so that newbranch is the current branch. New commits you make at this point will add to branch newbranch.

(If that's not what you want—e.g., if you want to add new commits to your existing branch_A—you'd run git checkout branch_A here again. Note how the only thing we're doing in Git here is manipulating all the files in the working tree while selecting some particular branch name to act as the current branch.)

Now that you are on the target branch into which you'd like to write a new commit that has some file some name, you can create an empty file with that name:

cp /dev/null newfile.html

or:

: > A_Folder/A.html

(Remember, the contents of both files, from the two branch tips, are in /tmp/A_File.html and /tmp/B_File.html. So we don't need to preserve the existing A_Folder/A.html content. We just want an empty file.)

You can now simply blat the two /tmp files together into a single file. However, because of the nature of HTML files, you'll probably want to edit the result to take out some redundant header and footer lines. You might also want to re-arrange the contents in some way. Do all of that with any programs you like. Git is not involved in this process! The file newfile.html or A_Folder/A.html is in your working tree, not in Git; you can do anything you like to it, with any process you like.

Once the file has the content you want to put in a new commit, simply use git add to add the updated or new file:

git add A_Folder/A_File.html

so that you update Git's index, i.e., the files (and content) that Git will put into the next commit you make. Then, run git commit to make a new commit, which Git will add to your current branch.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Your answer is very detailed and useful, But in large scale files, Combining the 2 files manually is very hard specially when conflicts are existed. I wanted git to do the combination process and I get notifications about conflicts and where they are. I handle them and the combination is done. Is there a way to do that?. I read about `merge-file` But I didn't get how can I use it in my case specially when one of the 2 files is not in the same directory. Thank you for your answer. – Mohamed AbdelAzeem Dec 09 '20 at 17:24
  • Conflicts cannot exist without a third input file. Conflicts arise because we compare the third input, the *merge base*, against each of the two branch-tip inputs. These produce two sets of *changes to make to the base*. The conflicts occur if, during the combining of the two changes, one of the pieces of one change (e.g., "add these three lines after line 42") collides with one of the pieces of another change (e.g., "delete lines 42 and 43"). – torek Dec 09 '20 at 20:42
  • Without a merge base file, we see only things like "file A says X and Y, file B says X and Z". We don't know if that's because both Y and Z should be added, or Y was initially present and file A is unchanged so that file B is telling us that Y was wrong and should be replaced with Z. – torek Dec 09 '20 at 20:43