Asked  6 Months ago    Answers:  5   Viewed   14 times

I have a repository in Git. I made a branch, then did some changes both to the master and to the branch.

Then, tens of commits later, I realized the branch is in much better state than the master, so I want the branch to "become" the master and disregard the changes on master.

I cannot merge it, because I don't want to keep the changes on master. What should I do?

Extra: In this case, the 'old' master has already been push-ed to another repository such as GitHub. How does this change things?

 Answers

56

The problem with the other two answers is that the new master doesn't have the old master as an ancestor, so when you push it, everyone else will get messed up. This is what you want to do:

git checkout better_branch
git merge --strategy=ours master    # keep the content of this branch, but record a merge
git checkout master
git merge better_branch             # fast-forward master up to the merge

If you want your history to be a little clearer, I'd recommend adding some information to the merge commit message to make it clear what you've done. Change the second line to:

git merge --strategy=ours --no-commit master
git commit          # add information to the template merge message
Tuesday, June 1, 2021
 
oroshnivskyy
answered 6 Months ago
93

No you cannot force a file that is already committed in the repo to be removed just because it is added to the .gitignore

You have to git rm --cached to remove the files that you don't want in the repo. ( --cached since you probably want to keep the local copy but remove from the repo. ) So if you want to remove all the exe's from your repo do

git rm --cached /*.exe

(Note that the asterisk * is quoted from the shell - this lets git, and not the shell, expand the pathnames of files and subdirectories)

Tuesday, June 1, 2021
 
Slinky
answered 6 Months ago
40

It is indeed impossible in general. Git records only1 the single commit-ID (SHA-1) to which a reference name (such as a branch or tag) points. The history of that commit is determined solely by that commit's parent IDs, which do not record branch-names. When you push to a remote, your "push" operation sends the SHA-1 of the commit you're pushing (plus more SHA-1s for any other linked objects—trees and files, parent commits, etc—plus the contents of all those objects, as needed based on what's missing on the remote), and asks the remote to set its branch to point to the new SHA-1.

In other words, you tell the remote: "here, have commit 1234567, and set branch label ddd = 1234567". It may tell you "to do that I need five other commits", one of which you have labeled as bbb, but if you don't tell the remote "oh by the way set label bbb to this other commit too" then it won't have that information anywhere.


1This is a bit of an overstatement: git also records, in the reflog, each SHA-1 that is stored in a label, including branch labels. It is therefore possible to walk back through the label's history to "figure out where it started". There are two limits on this though: reflogs are purely local, never transmitted by fetch or push; and reflogs expire, generally after 90 days in these cases (although this is configurable and there are additional complexities). So as long as we say there's a push step, or allow more than 3 months to pass, there's no way to tell.

Sunday, August 15, 2021
 
xenon
answered 4 Months ago
19

If you tell git to ignore a directory, it will completely ignore everything inside that directory. This means git cannot match your exclude because git is simply not looking at it.

The only way to use excludes in a meaningful way is for a single directory, where you ignore everything but some folder like this:

/some/path/*
!/some/path/foo

This will ignore all entries but foo directly under /some/path.

But, most of the time it is much clearer to just explicitly ignore things than using excludes.

Thursday, August 19, 2021
 
Scott Kausler
answered 4 Months ago
46

you are almost done.

Assume you have made a commit on your development files. Then..

git branch experimental_stuff

git reset --hard HEAD^ (go back one previous commit of your master branch to continue your development)

Assume you have not made a commit on your development files. Then.. you need to save your current changes to a temporary directory

git stash

git checkout -b experimental_stuff (create and change branch to experiental_stuff)

git stash pop (populate the temporary directory into experimental branch)

git checkout master (return back to master, and no need to go back the previous commit this time as you don't have that commit)

Thursday, September 23, 2021
 
davka
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share