<jupyter_start><jupyter_text>Branch and RebaseIn this notebook you will work with two separate repositories, one where you will use the `git merge` command and another where you will use `git rebase` command to merge your files. Once both commands complete successfully, you will compare the results across both repositories using `git log`Start by creating a repository where you use the `merge` command<jupyter_code>!git init merge_repo
%cd merge_repo<jupyter_output><empty_output><jupyter_text>The repository will store a list of colors from the business leader.<jupyter_code>%%bash
git config --global user.email "<EMAIL>"
git config --global user.name "<NAME>"
echo "Red
White
Blue" > colors
%%bash
git add colors
git commit -m 'initial colors'<jupyter_output><empty_output><jupyter_text>In production, you should expect `develop` branch that is separate from `master`. Here, to make the branch tree easier to explain, the issue specific branches are created directly from `master`<jupyter_code>!git branch yellow
!git branch green<jupyter_output><empty_output><jupyter_text>One of the developers works on resolving the issue by adding `yellow` to the file.<jupyter_code>%%bash
git config --global user.email "<EMAIL>"
git config --global user.name "<NAME>"
!git checkout yellow
%%bash
echo "Yellow" >> colors
cat colors
!git commit -am 'added yellow'<jupyter_output><empty_output><jupyter_text>The other developer works on adding color `green`.<jupyter_code>%%bash
git config --global user.email "<EMAIL>"
git config --global user.name "<NAME>"
!git checkout green
%%bash
echo "Green" >> colors
cat colors
!git commit -am 'added green'<jupyter_output><empty_output><jupyter_text>In the order of the commits, yellow was added first, followed by green. Let's suppose that the results of the `green` branch need to be merged into `yellow` for the latter to be resolved.<jupyter_code>!git checkout yellow<jupyter_output><empty_output><jupyter_text>Just confirming the status of `HEAD`, you are on the `yellow` branch, trying to merge the `green` branch files into `yellow`<jupyter_code>!git log --graph --decorate --all --oneline<jupyter_output><empty_output><jupyter_text>The multiline log also confirms that `yellow` was committed before `green`.<jupyter_code>!git log --graph --decorate --all<jupyter_output><empty_output><jupyter_text>Since the are no untracked files and you just checked out `yellow`, the output of the `status` command confirms that the working tree is clean<jupyter_code>!git status<jupyter_output><empty_output><jupyter_text>The recursive (three way) merge is expected to result in a conflict since the same lines of the `colors` file were modified in both the `yellow` and the `green` branches.<jupyter_code>!git merge green
!cat colors<jupyter_output><empty_output><jupyter_text>At this point, the developer working on the merge must choose from one of the three options:* pick the  lines from `HEAD` (i.e. `yellow`)* pick the lines from `green`* combine the lines from both `HEAD` and `green`If the developer does not know who worked on a specific issue, it is possible to use `git blame` to find out who committed conflicting changes.<jupyter_code>!git blame colors<jupyter_output><empty_output><jupyter_text>At this point the developer should know that both `yellow` and `green` issues tried to add colors to the file, so the right option is to combine the results.<jupyter_code>%%writefile colors
Red
White
Blue
Yellow
Green<jupyter_output><empty_output><jupyter_text>Once the file is modified, it should be re-staged for the commit using either an explicit `git add` or using `git commit -a` option.<jupyter_code>!git add colors
!git commit -m 'merged colors'<jupyter_output><empty_output><jupyter_text>Great! The output of `git log` confirms that the recursive merge completed as expected.<jupyter_code>!git log --graph --decorate --all<jupyter_output><empty_output><jupyter_text>The branching structure created using recursive merge maintains detailed records of the merge order. Detailed records are valuable for internal development purposes, such as trying to understand the history of the changes, including who made the merges and when. However some branches (e.g. `release`) in Git are used for code distribution to external teams. Having too much detail about recursive merges in a publicly facing branch can be distracting for someone just trying to understand what features were added and when. One of the advantages of `git rebase` is the ability to "clean up" the history of a branch.<jupyter_code>%cd ..<jupyter_output><empty_output><jupyter_text>To start, let's reproduce the state of the `colors` file used in the previous example in a separate repository called `rebase_repo`. The next cell also creates the two issue branches to add yellow and green colors.<jupyter_code>%%bash
rm -rf rebase_repo
git init rebase_repo
cd rebase_repo
git config --global user.email "<EMAIL>"
git config --global user.name "<NAME>"
echo "Red
White
Blue" > colors
git add colors
git commit -m 'initial colors'
git branch yellow
git branch green
%cd rebase_repo<jupyter_output><empty_output><jupyter_text>Just as in the previous example, the `yellow` issue is resolved first.<jupyter_code>%%bash
git config --global user.email "<EMAIL>"
git config --global user.name "<NAME>"
!git checkout yellow
%%bash
echo "Yellow" >> colors
cat colors
!git commit -am 'added yellow'<jupyter_output><empty_output><jupyter_text>Followed by the resolution of the `green` issue.<jupyter_code>%%bash
git config --global user.email "<EMAIL>"
git config --global user.name "<NAME>"
!git checkout green
%%bash
echo "Green" >> colors
cat colors 
!git commit -am 'added green'
!git checkout yellow
!git log --graph --decorate --all --oneline
!git status<jupyter_output><empty_output><jupyter_text>At this point, the state of this repo is identical to the state of the repo in the previous example.Notice that the next cell is using `git rebase` instead of `git merge` that you have seen earlier. Remember that by default the rebase operation assumes that the rebase should done to the `HEAD`. In other words `git rebase   ` uses `HEAD` as the default value of `` unless another branch or a commit is specified explicitly as an argument to the `rebase` command.<jupyter_code>!git rebase green<jupyter_output><empty_output><jupyter_text>Not surprisingly, the rebase results in a merge conflict because the same lines were modified in the `colors` file across the `yellow` and `green` branches.<jupyter_code>!cat colors<jupyter_output><empty_output><jupyter_text>Just as in the last example, the merge conflict is resolved by using all the lines from all the modifications to the colors file.<jupyter_code>%%writefile colors
Red
White
Blue
Yellow
Green<jupyter_output><empty_output><jupyter_text>Before a rebase can complete, the modified files must be re-staged.<jupyter_code>!git add colors<jupyter_output><empty_output><jupyter_text>To complete the rebase use the `continue` argument as in the next cell.<jupyter_code>!git rebase --continue<jupyter_output><empty_output><jupyter_text>Note the linear and ordered structure of the resulting `git log` and compare that to the detailed branching history of the example where you used the `git merge` operation.<jupyter_code>%cd ../rebase_repo
!git log --graph --decorate --all --oneline
%cd ../merge_repo
!git log --graph --decorate --all --oneline<jupyter_output><empty_output><jupyter_text>You might expect that the order of the log is also the chronological order of the commits. The `rebase` log can be misleading. Take a look at the timestamps in the merge log, and notice that it correctly preserves the details of the changes. Although the `merge` log is more difficult to understand, it is more accurate.<jupyter_code>%cd ../merge_repo
!git log --graph --decorate --all<jupyter_output><empty_output><jupyter_text>In contrast, the "cleaned up" history in the `rebase` log reports that the resolution of the `yellow` branch happened after the resolution of the `green` branch. However checking the stamps shows that not to be the case.<jupyter_code>%cd ../rebase_repo
!git log --graph --decorate --all<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08240752044927359, 'fraction_numerical': 0.0, 'mean_word_length': 5.775847808105873, 'pattern_counts': {'":': 0, '<': 117, '<?xml version=': 0, '>': 127, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '26', 'dir': 'jupyter-structured-clean-dedup', 'id': '592876', 'license': 'Apache-2.0', 'n_tokens_mistral': 2376, 'n_tokens_neox': 2316, 'n_words': 1037, 'path': 'git0/Demo_Branch_and_Rebase.ipynb', 'repo_name': 'nsingh216/edu', 'size': '8295'}