0

Here is my current situation. I created another branch and modified my code on the branch. Then I git commmit on the branch.

Now, when I tried to push the commit to my cloud repository, it showed "all up-to-date". Then I noticed that I forgot moving back to the master branch, so I tried "git checkout master".

Now, all the code modification as well as the temporarily created branch seem to have gone away. Now, "git branch" only shows "master".

In this case, can I regain the code modification I made on the other branch? I did not know "git checkout" would destroy all the code I modified on the other branch, as I thought it just switches to another branch...

Blaszard
  • 30,954
  • 51
  • 153
  • 233
  • `git reflog` ? But the described situation is pretty weird. Are you sure that you have actually committed your changes? – user3159253 Sep 02 '17 at 00:13
  • And yes, indeed, `git checkout ` just changes active branches. – user3159253 Sep 02 '17 at 00:14
  • @user3159253 Yes, `git branch` showed `* (HEAD detached from 7830210)` as well as `master`. And then I ran `git checkout HEAD` and everything has gone away... – Blaszard Sep 02 '17 at 00:14
  • Yeah, don't detach things. You need to actually *create* a branch. – o11c Sep 02 '17 at 00:15
  • Also note that `git push` only pushes *existing* branches, not new ones. – o11c Sep 02 '17 at 00:15
  • `git reflog` showed `7830210 (HEAD -> master) HEAD@{0}: checkout: moving from e4c58... to master` and `e4c58...` is a commit that I tried to "git push". – Blaszard Sep 02 '17 at 00:17
  • Then `git show e4c58...` and `git show 7830210` – user3159253 Sep 02 '17 at 00:22
  • Ah, I got it. It is because of the detached HEAD; and I must create a new branch (`git checkout -b new_branch`) and checkout to `master`, and then merge...right? – Blaszard Sep 02 '17 at 00:25
  • Likely you had been working on a detached head before switching the branches, so the lost branch simply doesn't have a name. Check `git show ....` output and if the lost changes are one of the refs, then use `git branch my-lost-and-found-branch ` to actually create a branch corresponding to the changes you have made so far. Then you'll be able to switch to that branch using the regular `git checkout ` approach – user3159253 Sep 02 '17 at 00:25

1 Answers1

1

Here is my current situation. I created another branch and modified my code on the branch. Then I git commmit on the branch.

Well, yes and no. See What exactly do we mean by "branch"?

As in the comments below your question, you did:

git checkout <some-hash-ID>

which checks out a specific commit, as a sort of go back in time to when this was the current commit operation. Git calls this kind of git checkout a "detached HEAD", and prints a huge warning (in any modern Git—very old Git, 1.7 era, was pretty quiet about it, as I recall), because it's easy to start committing away in this situation.

You then made new commits. In Git, this is a thing you can do, even if you're not on any branch, i.e., if you're in this detached HEAD mode. Git goes ahead and makes new commits, and—as in that other question—those new commits form one kind of branch, what I like to sometimes call a DAGlet.

Since there's no name involved, though, the only name you have for these new commits is their raw hash IDs, or—at least for the moment—HEAD. The name HEAD works up until you re-attach your HEAD by running, e.g., git checkout master.

Once you've reattached your HEAD (so that HEAD just means master which then means whichever commit is the tip of the branch named master), the name HEAD stops working to mean the commits you made while you were carrying your HEAD around in your arms, like some sort of ghoul chasing Ichabod Crane.

We can draw the situation like this. You probably did git checkout 7830210, so we know that commit's hash ID; I think e4c58... is the new commit you created. There are more commits whose ID we don't know, and really don't care about, which we can represent as round dots, o. So while your HEAD was rolling around loosely :-) you had this:

...--o--7830210...--o--o   <-- master
           \
          e4c58...   <-- HEAD

You then told Git to re-attach HEAD to master, giving:

...--o--7830210...--o--o   <-- master (HEAD)
           \
          e4c58...   [no name -- abandoned]

To manipulate the new commit more generally, you will need to give it a name. Git being Git, there are many ways to do that. The simplest at this point is to use git branch, which can create a new branch when given a commit hash ID:

$ git branch xyzzy-branch e4c58

which gives us:

...--o--7830210...--o--o   <-- master (HEAD)
           \
          e4c58...   <-- xyzzy-branch

(note that your HEAD remains untouched here, so it's still attached to master).


DAGlet is an invented word, deliberately punning from both the real word aglet, which means one of those plastic-covered shoelace tips, for instance, and DAG plus the diminutive suffix -let. DAG is a common computer science acronym for Directed Acyclic Graph. A DAGlet is just any useful snippet of a bigger DAG. We only care about snippets that end with a name pointing to it, or—in some cases—with no name pointing to them any more, as in this particular case. By wrapping them up in metaphorical plastic, we make it easy to grab hold of them and use them: voila, DAGlets.)

As far as I know, I invented this term. I see the word DAGlet also used in an IEEE paper, but I used it earlier. (It's also part of the name of a place—it appears to be a small oasis in the Sahara—in Algeria: Daglet Lagrouba.) Still, the diminutive suffix is kind of an obvious formation.

torek
  • 448,244
  • 59
  • 642
  • 775