git-guide/merging.md

124 lines
6.1 KiB
Markdown
Raw Normal View History

2024-05-03 16:19:31 +00:00
# Bringing code back together
Merging is a way of getting code from one branch to another, thats to say taking the changes from say the develop branch and bringing those into the main branch for example. You can do merge requests (pull requests on Github) either via the CLI or in the web gui. Lets take a look at the web gui first.
2024-05-03 16:19:31 +00:00
## Merge Requests in Gitlab
We'll use our example of having a branch called **issue 99**. The first thing we need to do is push some code changes to that branch. This effectively moves the HEAD of the branch (issuse 99) forward from the point it was first split. Git now knows theres changes and it's ahead. You'll get a message like this in Gitlab when you commit the code and view the branch:
![Message in Gitlab after pushing code to a branch](./img/create-merge.png)
Go ahead and click create merge request. You'll now see a commit message that shows you whats changing and it'll use data from the commit message to populate the merge request.
![Merge request ready to go](./img/ready-merge.png)
Now if you have merge conflicts instead of it saying **Ready to Merge** you'll have a red icon and a merge conflict message. You'll need to resolve the merge conflict before you can continue. If you do fix things make sure you comment it in the activity window. Optionally you can opt to delete the source branch, which effectively closes it off as the code is moved back into the main branch in this case. I personally like doing this as it tidies up the feature branches.
Now hit the blue merge button and you'll get the notification:
![Merge COmpleted](./img/merged.png)
You're all done, the code is merged and if you opted to delete the source branch you'll now be back to having just the one branch in your repository which is called main.
2024-05-03 16:19:31 +00:00
## Merging via the CLI
Lets take our example of making a branch for **issue 99**, the diagram below shows the current state of the git repository.
```mermaid
gitGraph
commit
commit
branch issue99
checkout issue99
commit
checkout main
commit
commit
```
Merging this is pretty simple, you can do it with the following instructions.
```bash
# Switch back to the main branch
git checkout main
# Merge the branches
git merge issue99
# Push the changes to the remote repository
git push
```
The diagram below shows what happened to our repository and how it got merged or flattened back into the **main** branch.
```mermaid
gitGraph
commit
commit
branch issue99
checkout issue99
commit
checkout main
commit
commit
merge issue99
commit
```
2024-05-03 16:32:19 +00:00
## Merge conflicts
When working with other developers you're all going to be cloning and pulling the code from the remote repository to start with and then committing and pushing your changes back. Now this is where it can get messy. Let's say there's a file called **header.html** in your repository and you and another developer change that file and push it back to remote repository and the same branch (or when branches are merged). This could end up in what's known as a **merge conflict**.
Basically you have both created a different version of the file from the initial clone so what happens now?
Which one should be the one stored. Well this is where git is really clever. It accepted the first persons commit and push without issues, the second person however will be notified of the conflict and be presented with some options. They will be asked to review the file locally and will be given a version of **header.html** that contains a diff showing both users contributions. You can then resolve this conflict by creating a merged version of both of your files or accept their changes or your changes only.
The way to read the merge conflict is to look in the affected file(s) in your code editor and check for the merge markers ```<<<<<<<```, ```=======``` and ```>>>>>>>``` which highlights the conflicting sections. You decide which changes to keep, remove or modify by deleting the lines you don't want including the merge markers and then save the file.
A good way to minimise this happening to you is to frequently run ```git pull``` in your working directory to keep up to date with others work, however, whilst this works for small teams larger teams will want to consider something more robust so they don't keep tripping over each other. This is where branches come in!
## Cherry-picking
Sometimes you don't want to merge an entire branch but want to select certain features/files to update only, and this is another good reason why to commit regularly as it gives you more granular options. For pulling in the changes you want you can use **cherry-picking**, that is selectively incorporates changes from one branch to another.
In order to do this you need to get the commit hash, which in Gitlab can be found in the right hand corner of the project code page, or you can use the command ```git log```
![Commit hash](./img/commit-hash.png)
When you identify the commit witht he changes you want run the following commands:
```bash
git checkout target_branch
git cherry-pick <commit-hash>
git push origin target_branch
```
Now those changes will be selectively merged into your current working directory. Here we can see that the changes from develop have been merged back into the main branch, and the developer working on the release branch doesn't want to pull fromt he HEAD of main or develop for changes, instead they **cherry-pick** the point in time where the develop branch was merged back into main. Heres a visulalisation of that:
```mermaid
gitGraph
commit
branch develop
branch release
commit
checkout main
commit
checkout develop
commit id:"B"
checkout main
merge develop id:"MERGE"
commit
commit
checkout release
cherry-pick id:"MERGE" parent:"B"
commit
commit
checkout develop
commit
commit
```
---
##### Follow me for more guides
2024-05-03 10:16:51 +00:00
[<img src="./img/mastodon.png" width="4%">](https://awscommunity.social/@Ric) [<img src="./img/linkedin.png" width="4%">](https://www.linkedin.com/in/richarvey/)