mirror of
https://gitlab.com/ric_harvey/git-guide.git
synced 2024-11-23 20:24:02 +00:00
127 lines
No EOL
6.3 KiB
Markdown
127 lines
No EOL
6.3 KiB
Markdown
# Bringing code back together
|
|
|
|
Merging is a way of getting code from one branch to another, that's 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.
|
|
|
|
## 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 (issue99) forward from the point it was first split. Git now knows there's 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 what's 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.
|
|
|
|
## 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
|
|
```
|
|
## 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 with the 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 from the HEAD of main or develop for changes, instead they **cherry-pick** the point in time where the develop branch was merged back into main. Here's a visualisation 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
|
|
|
|
[<img src="./img/mastodon.png">](https://awscommunity.social/@Ric) [<img src="./img/gitlab.png">](https://gitlab.com/ric_harvey) [<img src="./img/linkedin.png">](https://www.linkedin.com/in/richarvey/)
|
|
|
|
<div align=center>
|
|
[Git Guide](https://gitlab.com/ric_harvey/git-guide) by [Ric Harvey](https://awscommunity.social/@Ric) is licensed under [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/?ref=chooser-v1") |