GIT-stakes

quick fixes2 Parent ProblemFixing 2 Parents ProblemGit RevertGit Revert - MOREChecking Git ConfigGit Push Overview

choose your own adventure – git fixes

https://sethrobertson.github.io/GitFixUm/fixup.html


remove local commits

git checkout master // Make sure you are on correct branch (If not doesn't work)
git reset --hard origin/master // Reset local changes to origin/
git remote -v

If you have more than one remote, the command lists them all.

git remote -v
Pushing to Your Remotes

When you have your project at a point that you want to share, you have to push it upstream. The command for this is simple: git push . If you want to push your master branch to your origin server (again, cloning generally sets up both of those names for you automatically), then you can run this to push any commits you’ve done back up to the server:

$ git push origin master

This command works only if you cloned from a server to which you have write access and if nobody has pushed in the meantime. If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You’ll have to fetch their work first and incorporate it into yours before you’ll be allowed to push. See Git Branching for more detailed information on how to push to remote servers.

Inspecting a Remote

If you want to see more information about a particular remote, you can use the git remote show command. If you run this command with a particular shortname, such as origin, you get something like this:

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

It lists the URL for the remote repository as well as the tracking branch information. The command helpfully tells you that if you’re on the master branch and you run git pull, it will automatically merge the remote’s master branch into the local one after it has been fetched. It also lists all the remote references it has pulled down.

That is a simple example you’re likely to encounter. When you’re using Git more heavily, however, you may see much more information from git remote show:

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch                     pushes to dev-branch                     (up to date)
    markdown-strip                 pushes to markdown-strip                 (up to date)
    master                         pushes to master                         (up to date)

This command shows which branch is automatically pushed to when you run git push while on certain branches. It also shows you which remote branches on the server you don’t yet have, which remote branches you have that have been removed from the server, and multiple local branches that are able to merge automatically with their remote-tracking branch when you run git pull.
Renaming and Removing Remotes

You can run git remote rename to change a remote’s shortname. For instance, if you want to rename pb to paul, you can do so with git remote rename:

$ git remote rename pb paul
$ git remote
origin
paul

It’s worth mentioning that this changes all your remote-tracking branch names, too. What used to be referenced at pb/master is now at paul/master.

If you want to remove a remote for some reason — you’ve moved the server or are no longer using a particular mirror, or perhaps a contributor isn’t contributing anymore — you can either use git remote remove or git remote rm:

$ git remote remove paul
$ git remote
origin

Once you delete the reference to a remote this way, all remote-tracking branches and configuration settings associated with that remote are also deleted.

Git Commit 2 Parents

https://stackoverflow.com/questions/28079546/how-can-i-tell-what-happened-in-a-git-commit-with-two-parents-that-did-not-merge

How can I tell what happened in a Git commit with two parents that did not merge in the changes from the second parent?

n Gitk I can see a team member's commit (X) that has two parents, the first parent is his own previous commit (A), the other parent contains lots of other people commits (1 through 5). After his merge all changes made by other people (1 through 5 and others) are no longer present at X, B, C, etc…

A------------
              \
               X - B - C 
              /
1--2--3--4--5
           /
e--r--j--k
     /
l--m

If I diff commit X to commit A it shows no differences, if I diff commit X to commit 5 it shows all the missing changes. Also, at commit X, B, or C git log does not show changes that were made to files in commits 1 through 5. However, if I do git log –full-history then history does show the changes that were made in 1 through 5, but those changes are not still present in the actual file and history does not show them being being undone. So git log –full-history seems to contradict the current file contents.

I talked to the user who made commit X. He says he did not do a reset or rebase and he says he hasn't reverted any commits during the time in question. However, he says that he does sometimes do a pull origin master that results in everyone else's changes getting put in his index or working tree as if he had made those changes and not the actual authors of those changes. He says when that happens he does a fresh clone and does not push anything from that local repo to master because he believes Git has done something wrong.

Are the two things related (bad pull and bad merge)?

How can I tell exactly what happened so that we can avoid this in the future?

And what causes Git to sometimes put changes pulled from origin master to be placed in the local working directory or index as if they were local changes?

gitgit-mergegit-commitgit-pullgit-log

Share

Follow

asked Jan 22 '15 at 0:43

img
img
[Gbuy id=’147742′]

DAC

65755 silver badges1919 bronze badges

Add a comment

 

2 Answers

ActiveOldestVotes

 

 

12

 

 

 

However, he says that he does sometimes do a pull origin master that results in everyone else's changes getting put in his index or working tree as if he had made those changes and not the actual authors of those changes.

It sounds like he was getting merge conflicts but does not understand what they are. This is an extremely common problem, and unfortunately, we don't know a good way to avoid it (switching back to SVN doesn't avoid it, for example).

How could this happen, exactly?

Let's call your developers Alice and Bob. Alice made commits 1-5, and Bob made commits A and X. Here is a plausible history.

  1. Bob makes commit A.

  2. Alice makes commits 1-5, and pushes them to the central repository.

  3. Bob tries to push A, but can't, because his repository is out of date.

    $ git push
     ! [rejected]        master -> master (non-fast-forward)
    
  4. Bob then he does what you told him to do: he pulls first. However, he gets a merge conflict because commit A and commits 1-5 touch some of the same code.

    $ git pull
    Auto-merging file.txt
    CONFLICT (content): Merge conflict in file.txt
    Automatic merge failed; fix conflicts and then commit the result.
    
  5. Bob sees other people's changes in his working directory, and doesn't understand why the changes are there.

    $ git status
        both modified:   file.txt
    
  6. He thinks Git is doing something wrong, when in fact, Git is asking him to resolve a merge conflict. He tries to check out a fresh copy, but gets an error:

    $ git checkout HEAD file.txt  
    error: path 'file.txt' is unmerged
    
  7. Since it doesn't work, he tries -f:

    $ git checkout -f HEAD file.txt
    warning: path 'file.txt' is unmerged
    
  8. Success! He commits and pushes.

    $ git commit
    $ git push
    

The part where it gets harder

There are a lot of git tools out there. Seriously. Visual Studio and Xcode both come with Git integration, there are several other GUIs, and there are even multiple command-line clients. People are also sloppy with the way they describe how they use Git, and most developers are not quite comfortable enough with how Git works outside of the "pull commit push" workflow.

There was an excellent paper on this very subject not too long ago (I'm having a hard time finding it). Some of the conclusions were (forgive my memory):

  • Most developers don't really know how to use source control, except for a few really simple commands (commit, push).
  • When source control doesn't behave the way developers expect, they resort to tactics such as copy-pasting some command they don't quite understand to "fix things", adding the -f flag, or erasing the repository and starting again with a clean copy.
  • On development teams, it is often the case that only the lead developers really know what is going on in the repo.

So this is really an educational challenge.

I think the key lesson here that Bob needs to learn is that git pull is really just git fetch and git merge, and that you can get merge conflicts, and you need to act in a very conscientious and purposeful manner when resolving merges. This applies even when there are no reported conflicts… but let's not blow Bob's mind too much for now!

The other key lesson here is that lead developers need to take the time to ensure that everyone on the team can use source control correctly, and understands how pulling, pushing, branching, and merging are all related. This is a great opportunity for a lunchtime lecture: put together some slides, buy pizza, and talk about how Git works.

 

  • 2

    I thought Bob knew how to resolve merge conflicts, however, since you suspect this, I'll investigate what Bob actually does when conflicts arise. Will comment again after doing so. – DAC Jan 22 '15 at 1:42

  • 1

    He probably does know how to resolve merge conflicts, but some people don't realize that you can get merge conflicts when you do a git pull, and some people will run increasingly reckless commands when Git is doing something that they don't understand. – Dietrich Epp Jan 22 '15 at 3:40

  • Further discussion resulted in the user recalling that maybe he did do a rebase followed by a push after all. He also said that when a pull results in other people's changes in his working tree he becomes convinced that Git has done something wrong and re clones, and he uses the IDE's conflict resolution GUI tool. – DAC Jan 23 '15 at 1:11

  • 2

    I have come to realize how this usually happens. When pull origin master fails due to conflicts a git status will show all of the changes from the other branch as staged to commit. Bob thinks, those aren't my changes, panics and starts unstaging stuff. But actually, Bob must commit all those other people's changes after resolving the conflicts, otherwise, git will never merge those in. Solution is tell Bob, when you have conflicts, resolve conflicts and commit. Don't worry about other peoples changes in your staged, that's normal.DAC Apr 30 '18 at 20:52

  • 5

    Hello, I'm Bob. – Betlista Jan 12 '20 at 11:07

Revertin a merge commit (also a commit with 2 parents)

https://levelup.gitconnected.com/reverting-a-merge-commit-7de2e9114c7d

EVERTING A COMMIT

git revert

The revert command in git takes in a commit id and compares the changes with the parent. The delta or the diff is calculated and the negation of it applied as a new commit. In case the commit-sha is not specified, it is defaulted to the commit-sha of the HEAD commit.

img
img
[Gbuy id=’147743′]
img
img
[Gbuy id=’147744′]

Before Revert

$ git revert 9735432

This command creates a commit fbb1df5 on top of the HEAD negating the changes made by 9735432. The new HEAD will then point to the fbb1df5. The resultant tree will behave as if the commit 9735432 does not exist.

img
img
[Gbuy id=’147745′]
img
img
[Gbuy id=’147746′]

After Revert

THE MERGE COMMIT

Unlike other commits, the merge commit is a commit which has multiple (generally two) parents.

For instance, when a branch named feature is merged with master, a new commit is created on the branch master which has two parents, the previous head of master and the head of feature.

img
img
[Gbuy id=’147747′]
img
img
[Gbuy id=’147748′]

The branches before Merge

On merging the feature to master.

$ git checkout master

$ git merge feature

These commands create a new merge commit 1c32600.

img
img
[Gbuy id=’147749′]
img
img
[Gbuy id=’147750′]

The branches after merge

The merge commit 1c32600 has two parent commits

  1. 9735432 from master before the merge
  2. 1484b1a from branch feature

On running git show, the new commits display both the parents

$ git show

commit 1c32600da72208f8964da85fddb80e7dd43b15c9 (HEAD -> master)
Merge: 9735432 1484b1a

REVERTING THE MERGE COMMIT

While reverting the merge commit, the parent with which it needs to be compared should be specified. The parent may be specified with the -m flag in git revert followed by the parent-number.

The parent number is assigned from left. To revert the changes brought in by the feature branch, revert the commit with respect to the second parent (1484b1a).

$ git revert HEAD -m 1

This will revert all the changes made by the second branch (feature) on master. The resulting tree will behave as the branch feature was never merged to master.

img
img
[Gbuy id=’147751′]
img
img
[Gbuy id=’147752′]

git revert -m 2

Similarly, to revert the changes from the commits in the first parent of the merge commit run

$ git revert HEAD -m 1

This will revert all the commits that were made on the master after the feature branch was created leaving only the commits in the feature branch in the master.

img
img
[Gbuy id=’147753′]
img
img
[Gbuy id=’147754′]

git revert HEAD -m 1

In the above example,9745432 and b15b045 would be removed from the master branch leaving only the commits 1484b1a and 79fe70a and the older commits which are in feature.

Also, the master branch may be merged to feature branch.

$ git checkout feature
$ git merge master

img
img
[Gbuy id=’147755′]

Merge the master to feature branch

The changes in the commit in the 9745432 and b15b045 in the master branch will get included in the feature branch. This time for the merge commit the first parent is the original branch which is the commit 1484b1a itself whereas the commit in the master branch 9745432 is the second parent.

CAUTION

If the merge of master to the feature branch was unintentional. The correct way to undo it is to reset the branch. This can be done by running the following in the feature branch.

$ git reset HEAD~1

On the other hand, reverting a merge commit negates all the changes made by the branch of the specified parent.

For instance if after reverting the merge commit(177a8b) in the feature branch, it were merged back to master*,* it would wipe out the changes (9745432 and b15b045) made in the master branch.

img
img
[Gbuy id=’147756′]
img
img
[Gbuy id=’147757′]

Merging back after revert wipes out the changes

Now the master branch pointing to the commit a75ebc will not have the changes done in the commits 9745432 and b15b045.

Thanks for reading. Hope this was helpful. Please leave your comments if you have any questions or you feel something more needs to be added. Also do check out this blog Git Internals for a deeper explanation of how the git objects are structured under the hood.

The Problem

There are a number of work-flows you can use. The main point is not to break history in a published branch unless you've communicated with everyone who might consume the branch and are willing to do surgery on everyone's clones. It's best not to do that if you can avoid it.

Solutions for Published Branches

Your outlined steps have merit. If you need the dev branch to be stable right away, do it that way. You have a number of tools for Debugging with Git that will help you find the right branch point, and then you can revert all the commits between your last stable commit and HEAD.

Either revert commits one at a time, in reverse order, or use the <first_bad_commit>..<last_bad_commit> range. Hashes are the simplest way to specify the commit range, but there are other notations. For example, if you've pushed 5 bad commits, you could revert them with:

# Revert a series using ancestor notation.
git revert --no-edit dev~5..dev

# Revert a series using commit hashes.
git revert --no-edit ffffffff..12345678

This will apply reversed patches to your working directory in sequence, working backwards towards your known-good commit. With the –no-edit flag, the changes to your working directory will be automatically committed after each reversed patch is applied.

See man 1 git-revert for more options, and man 7 gitrevisions for different ways to specify the commits to be reverted.

Alternatively, you can branch off your HEAD, fix things the way they need to be, and re-merge. Your build will be broken in the meantime, but this may make sense in some situations.

The Danger Zone

Of course, if you're absolutely sure that no one has pulled from the repository since your bad pushes, and if the remote is a bare repository, then you can do a non-fast-forward commit.

git reset --hard <last_good_commit>
git push --force

This will leave the reflog intact on your system and the upstream host, but your bad commits will disappear from the directly-accessible history and won't propagate on pulls. Your old changes will hang around until the repositories are pruned, but only Git ninjas will be able to see or recover the commits you made by mistake.

 

  • If people already cloned bad pushes, and were notified – what should they do to have the same branch as in the remote? Do they have to do the same git reset --hard <last_good_commit>? – andrybak Oct 21 '15 at 17:43

  • 5

    If you are using commit tags, it's not <first_bad_commit>..<last_bad_commit>, but rather <last_good_commit>..<last_bad_commit>Yerke Feb 10 '19 at 9:47

 

If you've already pushed things to a remote server (and you have other developers working off the same remote branch) the important thing to bear in mind is that you don't want to rewrite history

Don't use git reset –hard

You need to revert changes, otherwise any checkout that has the removed commits in its history will add them back to the remote repository the next time they push; and any other checkout will pull them in on the next pull thereafter.

If you have not pushed changes to a remote, you can use

git reset --hard <hash>

If you have pushed changes, but are sure nobody has pulled them you can use

git reset --hard
git push -f

If you have pushed changes, and someone has pulled them into their checkout you can still do it but the other team-member/checkout would need to collaborate:

(you) git reset --hard <hash>
(you) git push -f

(them) git fetch
(them) git reset --hard origin/branch

But generally speaking that's turning into a mess. So, reverting:

The commits to remove are the lastest

This is possibly the most common case, you've done something – you've pushed them out and then realized they shouldn't exist.

First you need to identify the commit to which you want to go back to, you can do that with:

git log

just look for the commit before your changes, and note the commit hash. you can limit the log to the most resent commits using the -n flag: git log -n 5

Then reset your branch to the state you want your other developers to see:

git revert  <hash of first borked commit>..HEAD

The final step is to create your own local branch reapplying your reverted changes:

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

Continue working in my-new-branch until you're done, then merge it in to your main development branch.

The commits to remove are intermingled with other commits

If the commits you want to revert are not all together, it's probably easiest to revert them individually. Again using git log find the commits you want to remove and then:

git revert <hash>
git revert <another hash>
..

Then, again, create your branch for continuing your work:

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

Then again, hack away and merge in when you're done.

You should end up with a commit history which looks like this on my-new-branch

2012-05-28 10:11 AD7six             o [my-new-branch] Revert "Revert "another mistake""
2012-05-28 10:11 AD7six             o Revert "Revert "committing a mistake""
2012-05-28 10:09 AD7six             o [master] Revert "committing a mistake"
2012-05-28 10:09 AD7six             o Revert "another mistake"
2012-05-28 10:08 AD7six             o another mistake
2012-05-28 10:08 AD7six             o committing a mistake
2012-05-28 10:05 Bob                I XYZ nearly works

Better way®

Especially that now that you're aware of the dangers of several developers working in the same branch, consider using feature branches always for your work. All that means is working in a branch until something is finished, and only then merge it to your main branch. Also consider using tools such as git-flow to automate branch creation in a consistent way.


FETCH_HEAD is a short-lived ref, to keep track of what has just been fetched from the remote repository. git pull first invokes git fetch, in normal cases fetching a branch from the remote; FETCH_HEAD points to the tip of this branch (it stores the SHA1 of the commit, just as branches do). git pull then invokes git merge, merging FETCH_HEAD into the current branch.

The result is exactly what you'd expect: the commit at the tip of the appropriate remote branch is merged into the commit at the tip of your current branch.

This is a bit like doing git fetch without arguments (or git remote update), updating all your remote branches, then running git merge origin/<branch>, but using FETCH_HEAD internally instead to refer to whatever single ref was fetched, instead of needing to name things.

This depends a lot on what you mean by "revert".

Temporarily switch to a different commit

If you want to temporarily go back to it, fool around, then come back to where you are, all you have to do is check out the desired commit:

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

Or if you want to make commits while you're there, go ahead and make a new branch while you're at it:

git checkout -b old-state 0d1d7fc32

To go back to where you were, just check out the branch you were on again. (If you've made changes, as always when switching branches, you'll have to deal with them as appropriate. You could reset to throw them away; you could stash, checkout, stash pop to take them with you; you could commit them to a branch there if you want a branch there.)

Hard delete unpublished commits

If, on the other hand, you want to really get rid of everything you've done since then, there are two possibilities. One, if you haven't published any of these commits, simply reset:

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.

If you mess up, you've already thrown away your local changes, but you can at least get back to where you were before by resetting again.

Undo published commits with new commits

On the other hand, if you've published the work, you probably don't want to reset the branch, since that's effectively rewriting history. In that case, you could indeed revert the commits. With Git, revert has a very specific meaning: create a commit with the reverse patch to cancel it out. This way you don't rewrite any history.

# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes (non inclusive of first hash):
git revert 0d1d7fc..a867b4a

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

The git-revert manpage actually covers a lot of this in its description. Another useful link is this git-scm.com section discussing git-revert.

If you decide you didn't want to revert after all, you can revert the revert (as described here) or reset back to before the revert (see the previous section).

You may also find this answer helpful in this case:
How can I move HEAD back to a previous location? (Detached head) & Undo commits

 


Finding Merge Commits

p>https://stackoverflow.com/questions/3824050/telling-if-a-git-commit-is-a-merge-revert-commit

Figuring out if something is a merge is easy. That's all commits with more than one parent. To check for that, you can do, for example

$ git cat-file -p $commit_id

If there's more than one `parent' line in the output, you found a merge.

For reverts it's not as easy. Generally reverts are just normal commits that happen to apply the diff of a previous commit in reverse, effectively removing the changes that commit introduced. There're not special otherwise.

If a revert was created with git revert $commit, then git usually generates a commit message indication the revert and what commit it reverted. However, it's quite possible to do reverts in other ways, or to just change the commit message of a commit generated by git revert.

Looking for those generated revert commit message might already be a good enough heuristic for what you're trying to achieve. If not, you'd have to actually look through other commits, comparing their diffs against each other, looking of one is the exact reverse operation of another. But even that isn't a good solution. Often enough reverts are slightly different than just the reverse of the commit they're reverting, for example to accomodate for code changes that happened between the commit and the revert.


Identify the hash of the commit, using git log, then use git revert to create a new commit that removes these changes. In a way, git revert is the converse of git cherry-pick — the latter applies the patch to a branch that’s missing it, the former removes it from a branch that has it.


git push origin amd_qlp_tester will work for you. If you just type git push, then the remote of the current branch is the default value.

Syntax of push looks like this – git push . If you look at your remote in .git/config file, you will see an entry [remote “origin”] which specifies url of the repository. So, in the first part of command you will tell Git where to find repository for this project, and then you just specify a branch.

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
[remote "origin"]
        url = https://git.quantox.tech/Ciric/ns-forge-site.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "stage"]
        remote = origin
        merge = refs/heads/stage
[branch "Trenton-Stage-Mrg2Aug9"]
        remote = origin
        merge = refs/heads/trenton-ducatti

Previous versions

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
[remote "origin"]
        url = https://git.quantox.tech/Ciric/ns-forge-site.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "trentonsmpAug3"]
        remote = origin
        merge = refs/heads/trenton-ducatti

Branches

* Trenton-Stage-Mrg2Aug9
  smpAug11StageTrenton
  stage
  remotes/origin/HEAD -> origin/ns-site-setup
  remotes/origin/guerilla-porn
  remotes/origin/ns-site-setup
  remotes/origin/smp-trenton-ducatti
  remotes/origin/stage
  remotes/origin/trenton-ducatti

https://stackoverflow.com/questions/17756753/where-do-the-settings-in-my-git-configuration-come-from

Git checks four places for a configuration file:

  1. Your machine's system .gitconfig file.
  2. Your user .gitconfig file located at ~/.gitconfig.
  3. A second user-specific configuration file located at $XDG_CONFIG_HOME/git/config or $HOME/.config/git/config.
  4. The local repository's configuration file .git/config.

The settings cascade in the following order, with each file adding or overriding settings defined in the file above it.

  1. System configuration.
  2. User configuration.
  3. Repository-specific configuration.

You can see what each file has defined using the following commands:

# System, applies to entire machine and all users
$ git config --system --list
$ git config --system --edit

# User defined
$ git config --global --list
$ git config --global --edit

You can see what just the repository-specific file has defined by opening up the file .git/config for that repository.

If you're using MSysGit on Windows, you'll probably find your user ~/.gitconfig file where ever %homepath% points to if you use echo %homepath% from a Windows command prompt.

From the documentation for git config:

If not set explicitly with --file, there are four files where git config will search for configuration options:

  • $(prefix)/etc/gitconfig

    System-wide configuration file.

  • $XDG_CONFIG_HOME/git/config

Second user-specific configuration file. If $XDG_CONFIG_HOME is not set or empty, $HOME/.config/git/config will be used. Any single-valued variable set in this file will be overwritten by whatever is in ~/.gitconfig. It is a good idea not to create this file if you sometimes use older versions of Git, as support for this file was added fairly recently.

  • ~/.gitconfig

User-specific configuration file. Also called "global" configuration file.

  • $GIT_DIR/config

    Repository specific configuration file.

If no further options are given, all reading options will read all of these files that are available. If the global or the system-wide configuration file are not available they will be ignored. If the repository configuration file is not available or readable, git config will exit with a non-zero error code. However, in neither case will an error message be issued.

The files are read in the order given above, with last value found taking precedence over values read earlier. When multiple values are taken then all values of a key from all files will be used.

All writing options will per default write to the repository specific configuration file. Note that this also affects options like --replace-all and --unset. git config will only ever change one file at a time.

You can override these rules either by command-line options or by environment variables. The --global and the --system options will limit the file used to the global or system-wide file respectively. The GIT_CONFIG environment variable has a similar effect, but you can specify any filename you want.

Parent Number

https://stackoverflow.com/questions/7099833/how-to-revert-a-merge-commit-thats-already-pushed-to-remote-branch?lq=1

The -m option specifies the parent number. This is because a merge commit has more than one parent, and Git does not know automatically which parent was the mainline, and which parent was the branch you want to un-merge.

When you view a merge commit in the output of git log, you will see its parents listed on the line that begins with Merge:

commit 8f937c683929b08379097828c8a04350b9b8e183
Merge: 8989ee0 7c6b236
Author: Ben James
Date: Wed Aug 17 22:49:41 2011 +0100

Merge branch ‘gh-pages’

Conflicts:
README
In this situation, git revert 8f937c6 -m 1 will get you the tree as it was in 8989ee0,
and git revert -m 2 will reinstate the tree as it was in 7c6b236.

To better understand the parent IDs, you can run:

git log 8989ee0
and

git log 7c6b236


https://stackoverflow.com/questions/56521974/why-did-this-revert-fail

https://stackoverflow.com/questions/56521974/why-did-this-revert-fail

 

A typical merge commit would be shown as below in the git log command output.

commit dddfd0b6d529bfcdcd6515555ea1dcf186fe338
Merge: 6b5619b 40ad694
Author: Raja Anbazhagan <raja.anbazhagan@example.com>
Date:   Fri Jun 7 03:11:23 2019 +0530

    Merge branch 'xyz' into 'develop'

Here, You can see that the second line contains two short hashes. 6b5619b and 40ad694. Both of these are the top most commits of the branches that got merged.

Here 6b5619b is the top most commit id of the branch develop. And 40ad694 is the top most commit of the feature branch xyz.

I am telling you all this is because this information is important for what I am going to explain next.

When you are resetting or reverting a commit, it will try to figure out what had changed in that commit by comparing it to its ancestor commit.

In this case there are two ancestors 6b5619b and 40ad694 and GIT is now not sure from which ancestor it has to find the diff.

In these cases, the user will have to provide the appropriate parent commit id for the process to continue. Which is done with a flag -m followed by an ordinal number that represents where the parent commit id resides in the merge commit.

for my sample merge commit, possible -m values are 1 and 2. 1 for 6b5619b and 2 for 40ad694.

So if you want to revert your code on your develop branch, you should do

git revert -m 1 <merge-commit>

With -m 1 the git revert happens in relevance to develop branch (first parent of the merge). Passing -m 2 would result in the revert happening in relevance to the feature branch xxx

In general cases -m 1 is the one you should use. But that is not true for all cases.


GIT: PUSHING TO A REMOTE BRANCH WITH A DIFFERENT NAME

Normally when I do a push in git I do something like git push origin master, which really means push from the local branch named master to the remote branch named master. If you want to push to a remote branch with a different name than your local branch, separate the local and remote names with a colon:

git push origin local-name:remote-name

git push --dry-run origin Trenton-Stage-Mrg2Aug9:trenton-ducatti


git push origin Trenton-Stage-Mrg2Aug9:trenton-ducatti

https://www.toolsqa.com/git/git-push/

git push --dry-run <remote> <local_branch>

 

Throughout this whole course, we have had a detailed discussion of connecting the local repository with the remote repository and cloning a repository to the local machine. The content of this post is quite apparent. It is the next milestone in the series and information on the process of reflecting the changes that the user has done on the local system onto the GitHub account/remote repositories. Yes, we are going to learn about Git Push.

In this article, we are going to cover:-

  • What is Git Push Command?

  • How to Push Changes from Local Repository to Remote Repository in Git?

  • Options Available in Git Push command in Git

    • Prune Option in Git Push
    • Dry Ryn in Git Push
    • Atomic in Git Push
    • All in Git Push

Before starting the tutorial, we will request the user to learn the things given below.

Pre-Requisites for Pushing Changes in Git:

What is Git Push Command?

A git push command, when executed, pushes the changes that the user has made on the local machine to the remote repository. Once the users have cloned the remote repository and have made the necessary changes in their local device, these changes need to be pushed to the remote repository. The reason being, so that they are shared and used by other users. Git push command does it. These changes represent commitments performed on the repository and not the uncommitted changes (if any).

In addition to this, the changes that the user makes to the local system are of no worth to the contributors and viewers if the GitHub cloud does not reflect it. Imagine a user working on modifying some software (third-party repository), and merging the changes done is not easy. For instance, if you are working in a team on a single project, all the team members can push their code changes to the Github remote repository. Additionally, other members can fork and pull the changes from that remote repository. Therefore, it becomes effortless for multiple users to share their code change with all the team members.

To be able to push to your remote repository, you must ascertain that all your changes to the local repository are committed.

Consider Git push as a part of the synchronization process in Git. The synchronization happens between the local and remote repository where the source and the receiver may vary. There are a lot of other parts to sync and git push is one of the parts because it uploads the changes done on the local repository to keep the remote repository up to date. There is nothing complicated about it, and the concept is simple, just like its syntax.

Git Push Process

The above image suffices the concept in a nutshell.

  1. The user clones a repository as a first step to make some changes in the repository.
  2. Thereafter, they proceed to make the changes to the local system and add these changes to the staging area.
  3. Upon finalizing all the changes, the user then commits all the changes to the local repository.
  4. After their satisfaction, they push these changes to the remote server. Finally, it synchronizes the local and remote repository.

Syntax of Git Push command in Git:

Execution of Git push command happens by typing the following command:

git push <remote_repo> <branch_name>
  • remote_repo: This is the name (or alias) of the remote repository to which we are pushing the changes.
  • branch_name: This is the branch the user is pushing to the remote repository.

We will talk about branches in the Branches in the GitHub tutorial. But till then imagine that a branch in Git is similar to the branches in a tree. Every branch represents a new feature or modification under development. Additionally, the main branch is the stable code like the trunk of the tree, also called a master branch. Which, in turn, helps the unstable code of branches to stay away from the stable main code.

In the next section, we will see how to push the changes to the remote cloud repository.

How to Push Changes from Local Repository to Remote Repository in Git

To push some changes to the remote repository, the repository must, first of all, contain some commits on the local system. Therefore, in this section, we will first create some changes to the repository. Secondly, we will commit those changes, and finally, we will reflect them in the remote repository.

Before creating the changes onto the repository, ensure that you have performed the following operations:

  • You have forked a repository to the GitHub account.
  • You have cloned the same repository to the local machine.

Note: In this tutorial, we will use the ToolsQA repository that has already been forked and cloned in the previous tutorials. The user is free to use any public repository. However, the recommendation is to use the same repository for this tutorial is recommended.

As a good practice first, check that you have a clean repository through git status command (no pending changes to commit).

Git status command

The following lines appear after executing the git status command:

On branch master: Denotes that we are currently on the master branch. Since there are no other branches yet, we are on the master branch by default.

Your branch is up to date with origin/master: Origin is the name of the remote repository that we gave while connecting the local repository with the remote repository. Please refer to this [link*](https://www.toolsqa.com/git/local-repository-remote-repository/) to know more.*

  1. List all the files with the ls command in the repository.

ls command to List files

Since there is only one file (README.md is just instructions), let's make some changes to its content.

  1. Open the file using your favorite editor and make any changes to the file.
  2. We have changed the file to the following code.

changed web page html code

Note: This is a screenshot of the vi editor. You can use any editor of your choice.

  1. Add the changes made to the staging area and commit these changes.

Git Add - committing clone web_page

Note: GitHub and Git will recognize any change through commits only. If the user has not committed the changes and tries to push the changes to GitHub, it will display "Everything is up-to-date" message.

  1. Type the following command to push these changes into your GitHub repository and press enter.
git push origin master

git push command

Note: Please refer to the syntax section above to know about the syntax of this command.

  1. The user gets a prompt to provide the credentials by GitHub as a part of security. Provide your credentials and tap on the Login button.

github prompt to Provide credentials

  1. Once the user gets the approval and the changes merge, the user will get the following message in Git Bash.

git push command success message

Note: The last two lines are as follows:

https://github.com/harishrajora805/ToolsQA.git: The repository URL which reflects the changes.

1b4522a..285f559: This depicts the hash value of both branches. So, the hash value of the final commit reflected on GitHub is 285f559.

master -> master: The line master-> master shows the source branch from which merging happens to the destination branch. In the above scenario, both are master branches.

The line above the highlighted line written as Writing Objects: 100% is essential. In Git, one can tell, whether the push command has executed successfully or not, only by looking at this line. If it shows 100%, then all the changes have been successfully pushed onto the cloud.

Along with the simple, straightforward command we discussed above, like any other command in Git, we can use options while executing the command to achieve a specific task. For example, if you want to push all the branches, you would use all option and so on. Let's see some of the options in Git.

Options Available in Git Push command in Git

As mentioned in the last section, there are many options available in the Git push command that helps us achieve certain specific tasks with just one execution. In this section, we will take you through the essential and most used options in the git push command.

Prune Option in Git Push

–prune option in git push command will delete branch XYZ from the remote repository if there does not exist any branch with the same name in the local repository.

Usage: git push --prune remote XYZ

Dry Run Option in Git Push

This option will perform and show the execution of the git push command but will not send any updated to the remote repository.

Usage: git push --dry-run <remote> <local_branch>

Atomic Option in Git Push

Atomic option in Git Push provides an atomic operation on the remote repository, i.e., either every reference update or nothing at all.

git push --atomic <remote_repo> <working_branch>

All Option in Git Push

All options will push all the branches and their committed changes to the remote repository.

Usage: git push --all <remote>

By this, a Successful push operation completes. Don't relax just now; the job does not finish here. It is not just enough to push the changes to GitHub. The verification of these changes onto the account should happen. In addition to this, an analysis happens which tells how these changes get reflected. Let's analyze the difference and see if they update or not, in the next tutorial.

Scroll to Top