Git Notes
Imp points:
General points:
- Rename a branch -> First checkout to the branch which should be renamed then use git branch -m <new name>
- git detached head mode, nice blog here
- To see all remote branches, use gir branch -r
- If a remote branch exists with name test,which can be viewed using git branch -r. If we want to create a local branch for the same use git switch branch name.
This will do 2 actions:
1. Create a local branch with name test
2. Set up track top point to origin/test(which can be seen in .git/config file) - git fetch origin test3 or git checkout test3 -> only fetches test3 branches info from remote to local but git fetch gets info of all branches in remote origin
- when using git pull(above 2.27.0), we need to specify how to reconcile divergent branches, using opions discussed here else it wil promt the warning
- Before pulling the changes if we want to see want has changed in master, you can fetch the changes and go to remote/<branchname> (This is called detached head mode) and view all your changes.
If you feel good just get those changes. - When we use git pull, the changes of remote/<branch> are merged into local branch.So we don't need to specify origin <remote branch> but in case of fetch if we use git fetch, it will fetch info of all git remote branches.If you want any specific branch specify git fetch origin <branch name>
- when you perform 3 way recursive merge and see the log using git log then you shock because git log shows history from other branch as well
Instead use git log --first-parent or git log --graph(to see grapsh view)
more detailed explanation: here
or other solution is use --squash,which will wait for squashing to happen,so it replaces all the commit messages with single commit msg, which you should add immediately afterwards.
git merge --squash <branch name>
git commit -m "commit msg" - Improve your git log command by setting alias as shown here
- git diff -> without additional options, git diff lists all the changes in our working dir that are not staged for next commit(Basically diff betwwen working dir and staged contents)
- git diff HEAD -> lists all changes in the working tree since last commit.(Even changes which we are staged)
- Git stash basic commands here
- When you work on a branch and meanwhile you wanted to switch to another branch and before switching if you don't stash or commit changes then changes will commit to other branches(which is no good) if there are no conflicts
- Here conflict has a different meaning i.e if you want to switch to branch a from branch b, If you try to merge branch b into a then observe for coflict.(If fast forward mege is possible then you don't get any conflicts)
- If you get conflicts, git will intelligenly predict and it will promt error: unable to switch else i.e if no errors then it will carry the changes
You demonstrated nicely these two scenarios:
1. changes come with us
2. conflict happens
But, when I think about it, I still see conflicts every single time. Let me explain.
You have master and purple branches. Branch master has empty CSS, purple doesn't. So when you switched (with uncommitted changes) back to master, there wasn't conflict. How? Wouldn't there be conflict because master says "I don't have styles", and purple says "I have styles"? So, how is that not considered by a conflict?
I hoped you understood my confusion :D
Answer:
It's a good question! Suppose I have one branch "original" where I've made some commits and then I create a new branch from that original branch called "newFeature". Then I start working on newFeature, where I create a new file called puppies.css and then create a new commit. This commit and puppies.css only exists on the newFeature branch. The original branch does not have this commit, and it does not contain any additional new work.
If I then go to the original branch and try to merge in the changes from newFeature will we get a conflict or not? The newFeature branch has the puppies.css file. The original branch has no puppies.css file. Is that a conflict?
The answer is no, we don't get a conflict! "Disagreement" between branches is not what results in a conflict. In this case, Git can perform a fast forward merge because newFeature has all the same history as the original branch plus one new commit. So Git can easily bring that new commit over to the original branch.
On the other hand, if we also had new commits on the original branch that didn't exist on newFeature...then we would get a conflict. Git "thinks" in terms of commits. So if the original branch has commits that don't exist on newFeature, and newFeature has commits that don't exist on original...that's how we could get a conflict.
Returning to your original question about switching branches: Wouldn't there be conflict because master says "I don't have styles", and purple says "I have styles"? So, how is that not considered by a conflict? There won't be a conflict unless we have work that was done on master that doesn't exist on purple AND we have work on purple that doesn't exist on master. But that's not the case. Instead, we just have some work on purple that doesn't exist on master. So no conflict. Does that make sense or am I just confusing you with this massive essay!?
Git Interactive rebase:- The commit messages will be seen in reverse, the git reads msgs from the start and do all actions
- If you reword a commit message(i.e fixing typo in commit message) then it will change commit hash from that particular commit to all the way to the top(Because each commit stores its parents commit details(refer git internals))
- Difference between fixup and squash is both are used to meld other commit messsage into previous commit message.squash will comment the one which you want to discard so that you can edit it in next step but fixup just altogether deletes it. Detailed explanation with number 5 here
- drop will delete commit message and even changes made in that commit
- Either modifying files or creating files, before staging they will be in working dir, If we need to undo them then we have 2 options
- git checkout HEAD <filename> or git chekout -- <filename>(In older versions)
- git restore <filename>(In newer version)
With git restore we can even change the content of file how it looks like a couple or more comis ago.cmd for the same: git restore --source HEAD~1 <filename>(or even commit id instead of HEAD~1)
1. mixed reset: Will undo the latest commit and changes will be moved to working dir
We can even undo more than one commit
- It is very simple, if there are multiple conflicts while merging then it just stops with conflicts, we need to manually resolve them and we need to perform git add and git commit
- Identify the common ancestor: Git identifies the common ancestor commit between the feature branch and the main branch. This common ancestor serves as the base for the rebase operation.
- Create a temporary copy: Git creates a temporary copy of the feature branch.
- Check out the main branch: Git checks out the main branch, moving the HEAD pointer to the latest commit on the main branch.
- Apply the commits: Git starts applying the commits from the temporary copy of the feature branch onto the main branch. It goes through each commit, one at a time, and applies the changes introduced by that commit to the main branch.
- Handle conflicts: If there are conflicting changes between the commits being replayed and the state of the main branch, Git pauses the rebase process and asks you to resolve the conflicts. You need to manually modify the code to incorporate the desired changes and then continue the rebase process.
- Complete the rebase: Once all the commits have been applied successfully or conflicts have been resolved, Git completes the rebase by moving the branch pointer of the feature branch to the last replayed commit. The original commits from the feature branch remain intact, but the commit history has been modified to incorporate the changes onto the main branch.
Rebasing replays changes from one line of work onto another in the order they were introduced, whereas merging takes the endpoints and merges them together.
Do not rebase commits that exist outside your repository and that people may have based work on.
You can get the best of both worlds: rebase local changes before pushing to clean up your work, but never rebase anything that you’ve pushed somewhere.
Comments
Post a Comment