When contributors take too much time to push code to the remote repository, there’s a high chance to happen Merge Conflicts.
A merge conflict happen when same line of code was changed and git can’t fix it alone. So it must be solve manually.
The best practice to avoid it is to push and pull often to/from remote repository.
Continuous Integration: integrate your code changes frequently.
Parts of git:
git log
)Main players:
gitlab
# cloning a repo
git clone <repository-URL>
Inside the repository directory there’s a subdir named .git/
. It has information about the repository and is used only locally.
Working Directory –git add
–> Staging Area –git commit
–> Local repository
# status of local git repo
git status
# add a file to the staging area
git add FILENAME
# commit the files in the staging area to the local repository
git commit
# see the history of changes (commits) in the local repository
git log
# pushing the local repository content to the remote one
git push
Project locally is NOT a git repository yet:
# existing_directory is not yet a git repository
# (meaning: doesn't have a '.git' directory)
cd existing_directory
# say that this is going to be a git repo
git init
# set a remote repository for it
git remote add origin <git-repository-URL>
# adding files to staging area
git add .
# commit to local repo
git commit -m 'Initial commit'
# push to remote setting an upstream branch named 'master'
git push --set-upstream origin master
The concept of branches exist in order to cleanly divide the work of different developers.
Best practices is to create branches for each feature and each bugfix.
Examples:
feature/user-auth
- for the user authentication featurebugfix/user-auth-error
- for fixing the error in the user authentication
# show the current branch you're working
git branch
# pulling updates from the remote repository (which may include new branches)
git pull
# switching to another branch
git checkout <branchname>
# creating a new local branch and switch to it right away
git checkout -b <new-branchname>
# pushing the newly created local branch to the remote repo
git push -u origin <new-branchname>
NOTE before creating a new branch and start working on it, it’s import to switch back to master
, in order to base your branch on master.
Common practice: having the master
and the develop
branches
Keep only branches that are being actively being worked.
# delete a branch locally
git branch -d <branchname>
# delete a remote branch
git push <repo> --delete <branchname>
When you try to push changes to a repo and the remote repo has a commit (from another dev) you don’t have locally, you need to git pull
and it’ll automatically merge the changes into your repo by creating a new commit. This is useful but add some “pollution” to your commit history.
In order to avoid such pollution, use the command git pull -r
, and it’ll just insert the commit you don’t have before your commit.
# avoid "Merge branch..." pollution in commit history
git pull -r
Happens when more than one developer change code in the same line of a file. Even if you try to git pull -r
you’ll receive a CONFLICT
message.
When such situation happens YOU must tell git which change to take. Open the file where the conflict happens in your editor and fix the conflicts. And then git rebase --continue
.
# pulling remote changes and rebase
git pull -r
# a conflict happens, fix it in your editor
# continue with the rebase
git rebase --continue
# push changes to remote
git push
Used to exclude certain folders or files from git to be tracked.
# removing tracked-but-now-ignored files from the repository
git rm -r --cached removed_directory/
Useful link: https://gitignore.io/
Scenario where git stash
is useful:
git stash
git stash pop
# seeing the history
git log
# NOTE: 'detached HEAD' state means you are not in the most
# uptodate commit
# choose the commit hash you want to test
git checkout <commit-hash>
# if you want to create a new branch from the current state
git checkout -b <new-branch-name>
# if you want to go back to the latest commit
git checkout <branch-name>
Undoing and removing commits that were not yet pushed to the remote repository:
# reverting a commit
# the '--hard' option discards the changes made in the commits being reverted.
git reset --hard HEAD~1
# the number after the tilde '~' sets the amount of commits to be reverted
# example reverting last 3 commits:
git reset --hard HEAD~3
# reverting the commit but keeping the changes
# (this is equivalent to use --soft)
git reset HEAD~1
# once you're happy with the changes you've made, let's ammend that commit
git commit --amend -m 'commit message'
Undoing and removing commits that were already pushed to the remote repository
WARNING: Don’t do this in master or develop branch! Only do this when working alone in a branch!
# reverting a commit
git reset --hard HEAD~1
# force push a new commit history to the remote repository
git push --force
Reverting changes through a new commit actually changing the files to the previous state.
# create a new commit changing the commit but in the reverse way
git revert <commit-hash>
# example: you're on a new branch and the master branch was
# changed by another dev, and you want such changes in your
# new branch.
# go to the master branch and pull the changes
git checkout master
git pull
# go back to your branch
git checkout <branch-name>
# merge the changes from master into your branch
git merge master
Situations where you, as a DevOps Engineer, need git: