How can I git force changes to origin master without merging? - linux

git-2.16.2 on linux
I'm not terribly experienced with git push, so please bear with...
I made changes to a clone which was created from origin master. I want to push those changes to origin master without merging with what's there. I tried git push --force but that didn't seem to work even though the messaging seems to indicate that it did...
--> git push --force
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 597 bytes | 597.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0)
To /proj/projects/git_repos/mytool.git
+ eafc0ab...3155ce8 master -> master (forced update)
I say it didn't work because when I now do a git clone of origin master to make a new repo with the changes, the changes aren't there.
The reason I tried the --force is that I want all my local (committed) changes to basically clobber whatever's in origin master. I don't want to merge with whatever's there, although I can see why that's an important thing to be able to do in some circumstances. I'm basically looking for a shortcut around doing the git pull --rebase and all the merging (accepting everything I have locally and rejecting everything else), git add, git rebase --continue, etc... . I just want my local changes to replace whatever's in the origin master.
If there is a shortcut outside of git push --force that I can use to to avoid all the merging and just accept the local changes, that's good, because it'll save the history.
Thanks for any help

OK, I think my mistake was that I did a "git push --force" and not a git push --force origin master". Not sure where things get pushed to, but that appears to have worked.

Related

How to commit into a branch in git and show result into a git graph? [duplicate]

Using gitk log, I could not spot a difference between the effect of git merge and git merge --no-ff. How can I observe the difference (with a git command or some tool)?
The --no-ff flag prevents git merge from executing a "fast-forward" if it detects that your current HEAD is an ancestor of the commit you're trying to merge. A fast-forward is when, instead of constructing a merge commit, git just moves your branch pointer to point at the incoming commit. This commonly occurs when doing a git pull without any local changes.
However, occasionally you want to prevent this behavior from happening, typically because you want to maintain a specific branch topology (e.g. you're merging in a topic branch and you want to ensure it looks that way when reading history). In order to do that, you can pass the --no-ff flag and git merge will always construct a merge instead of fast-forwarding.
Similarly, if you want to execute a git pull or use git merge in order to explicitly fast-forward, and you want to bail out if it can't fast-forward, then you can use the --ff-only flag. This way you can regularly do something like git pull --ff-only without thinking, and then if it errors out you can go back and decide if you want to merge or rebase.
Graphic answer to this question
Here is a site with a clear explanation and graphical illustration of using git merge --no-ff:
Until I saw this, I was completely lost with git. Using --no-ff allows someone reviewing history to clearly see the branch you checked out to work on. (that link points to github's "network" visualization tool) And here is another great reference with illustrations. This reference complements the first one nicely with more of a focus on those less acquainted with git.
Basic info for newbs like me
If you are like me, and not a Git-guru, my answer here describes handling the deletion of files from git's tracking without deleting them from the local filesystem, which seems poorly documented but often occurrence. Another newb situation is getting current code, which still manages to elude me.
Example Workflow
I updated a package to my website and had to go back to my notes to see my workflow; I thought it useful to add an example to this answer.
My workflow of git commands:
git checkout -b contact-form
(do your work on "contact-form")
git status
git commit -am "updated form in contact module"
git checkout master
git merge --no-ff contact-form
git branch -d contact-form
git push origin master
Below: actual usage, including explanations.
Note: the output below is snipped; git is quite verbose.
$ git status
# On branch master
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: ecc/Desktop.php
# modified: ecc/Mobile.php
# deleted: ecc/ecc-config.php
# modified: ecc/readme.txt
# modified: ecc/test.php
# deleted: passthru-adapter.igs
# deleted: shop/mickey/index.php
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# ecc/upgrade.php
# ecc/webgility-config.php
# ecc/webgility-config.php.bak
# ecc/webgility-magento.php
Notice 3 things from above:
1) In the output you can see the changes from the ECC package's upgrade, including the addition of new files.
2) Also notice there are two files (not in the /ecc folder) I deleted independent of this change. Instead of confusing those file deletions with ecc, I'll make a different cleanup branch later to reflect those files' deletion.
3) I didn't follow my workflow! I forgot about git while I was trying to get ecc working again.
Below: rather than do the all-inclusive git commit -am "updated ecc package" I normally would, I only wanted to add the files in the /ecc folder. Those deleted files weren't specifically part of my git add, but because they already were tracked in git, I need to remove them from this branch's commit:
$ git checkout -b ecc
$ git add ecc/*
$ git reset HEAD passthru-adapter.igs
$ git reset HEAD shop/mickey/index.php
Unstaged changes after reset:
M passthru-adapter.igs
M shop/mickey/index.php
$ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks"
$ git checkout master
D passthru-adapter.igs
D shop/mickey/index.php
Switched to branch 'master'
$ git merge --no-ff ecc
$ git branch -d ecc
Deleted branch ecc (was 98269a2).
$ git push origin master
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 59.00 KiB, done.
Total 14 (delta 10), reused 0 (delta 0)
To git#github.com:me/mywebsite.git
8a0d9ec..333eff5 master -> master
Script for automating the above
Having used this process 10+ times in a day, I have taken to writing batch scripts to execute the commands, so I made an almost-proper git_update.sh <branch> <"commit message"> script for doing the above steps. Here is the Gist source for that script.
Instead of git commit -am I am selecting files from the "modified" list produced via git status and then pasting those in this script. This came about because I made dozens of edits but wanted varied branch names to help group the changes.
Merge Strategies
Explicit Merge (aka non fast-forward): Creates a new merge commit. (This is what you will get if you used --no-ff.)
Fast Forward Merge: Forward rapidly, without creating a new commit:
Rebase: Establish a new base level:
Squash: Crush or squeeze (something) with force so that it becomes flat:
The --no-ff option ensures that a fast forward merge will not happen, and that a new commit object will always be created. This can be desirable if you want git to maintain a history of feature branches.
In the above image, the left side is an example of the git history after using git merge --no-ff and the right side is an example of using git merge where an ff merge was possible.
EDIT: A previous version of this image indicated only a single parent for the merge commit. Merge commits have multiple parent commits which git uses to maintain a history of the "feature branch" and of the original branch. The multiple parent links are highlighted in green.
This is an old question, and this is somewhat subtly mentioned in the other posts, but the explanation that made this click for me is that non fast forward merges will require a separate commit.
The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature
Other answers indicate perfectly well that --no-ff results in a merge commit. This retains historical information about the feature branch which is useful since feature branches are regularly cleaned up and deleted.
This answer may provide context for when to use or not to use --no-ff.
Merging from feature into the main branch: use --no-ff
Worked example:
$ git checkout -b NewFeature
[work...work...work]
$ git commit -am "New feature complete!"
$ git checkout main
$ git merge --no-ff NewFeature
$ git push origin main
$ git branch -d NewFeature
Merging changes from main into feature branch: leave off --no-ff
Worked example:
$ git checkout -b NewFeature
[work...work...work]
[New changes made for HotFix in the main branch! Lets get them...]
$ git commit -am "New feature in progress"
$ git pull origin main
[shortcut for "git fetch origin main", "git merge origin main"]
What’s a fast-forward?
A fast-forward is what Git does when you merge or rebase against a branch simply ahead of the one you have checked-out.
Given the following branch setup:
You’ve got both branches referencing the same commit. They’ve both got precisely the same history. Now commit something to feature.
The master branch is still referencing 7ddac6c, while the feature has advanced by two commits. The feature branch can now be considered ahead of the master.
It’s now relatively easy to see what’ll happen when Git does a fast-forward. It simply updates the master branch to reference the exact commit that feature does. No changes are made to the repository itself, as the commits from the feature already contain all the necessary changes.
Your repository history would now look like this:
When doesn’t a fast-forward happen?
Fast-forwards don’t happen when changes have been made in the original branch and the new branch.
If you were to merge or rebase the feature onto master, Git would be unable to do a fast-forward because the trees have both diverged. Considering Git commits are immutable, there’s no way for Git to get the commits from feature into master without changing their parent references.

Performed HARD Reset on Git But Files are still Staged

I am using AWS SageMaker and unbeknownst to me the EC2 created a checkpoint for a .csv file that I added to .gitignore due to its size. Therefore, I accidentally added the checkpoint file to be committed.
To remove the file from staging, I performed a hard reset by executing git reset HEAD --hard.
I received the following response:
HEAD is now at c2770a8 add updates
When I executed git status, I was informed the following:
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
Consequently, I submitted git push origin master and I encountered the following error:
Counting objects: 15, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (15/15), 61.39 MiB | 5.80 MiB/s, done.
Total 15 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: cee6ca9f888bed2a49b7bbd5de9edb1a
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File data/.ipynb_checkpoints/traffic_crashes-checkpoint.csv is 212.62 MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/Morgan-Sell/Chicago-Traffic-Risk.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://github.com/Morgan-Sell/Chicago-Traffic-Risk.git'
(1) How come the reset is not clearing my staging?
(2) How do I know what corresponds to c2770a8?
Thanks!
The problem you have is that your problem file is already committed. Adding a file to .gitignore doesn't remove it from being committed. git reset --hard HEAD (and that's how you should write it, with options before arguments) also doesn't remove files that are already committed; it resets the working tree and index to the specified commit. Since the commit already contains the problem file, you haven't changed anything in it.
What you probably want to do is git reset --soft HEAD^, assuming the latest commit is the one in which you added the problem file. That will undo your latest commit and leave all of the files staged. You can then run git reset data/.ipynb_checkpoint to remove any staged files in that directory, and the commit again.
If you added the problem file in an earlier commit, then you'll want to do a git rebase -i COMMIT^ where COMMIT is the commit that added the problem file, and then mark the problem commit as edit instead of pick, save, and quit your editor. Then, when Git stops, run git rm -r --cached data/.ipynb_checkpoints && git commit --amend --no-edit && git rebase --continue which will remove the file and finish the rebase.

can't push to gitlab, failed and rejected

has been pulled, the result is still an error ! [rejected] dev->dev(non-fast-forward)
D:\PPI_Roketin\Project\astrowatch (dev)
λ git add resources/views/reals/_form.blade.php
D:\PPI_Roketin\Project\astrowatch (dev)
λ git commit -m "resources/views/reals/_form.blade.php"
[dev db5ac99] resources/views/reals/_form.blade.php
1 file changed, 2 insertions(+), 2 deletions(-)
D:\PPI_Roketin\Project\astrowatch (dev)
λ git push origin dev
To gitlab.com:roketin-stellar/astrowatch.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git#gitlab.com:roketin- stellar/astrowatch.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
error like this, why?
have done git checkout, and repeated the command, it's still an error like above
This is a classic git error. The problem is described in the error message: Updates were rejected because the tip of your current branch is behind, which means that there have been changes to the remote branch that you do not have locally. There are quite a few ways to fix this, one of which is also described in the git message: Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again.
If you do git pull origin dev this will merge whatever changes are made in the remote to your local branch. Once you fix the merge conflicts, you can then push the branch.
Another option would be to run a rebase by performing git pull --rebase origin dev, which will bring in the remote changes and rebase your commits on top of the remote commits. This will result in a cleaner git history.
The easiest for now would probably just doing a git pull, then once it's merged correctly, pushing to your remote.
I definitely recommend researching the git commands and learning how to find the resources correctly in the docs. There is a lot available online.
you can try git reset --hard HEAD
please remind that:
HEAD points to your current branch (or current commit), so all that git reset --hard HEAD will do is to throw away any uncommitted changes you have.
It's quite self explanatory, you need to keep yourself upto date with remote branch if you want to commit and it looks like git pull will overwrite files you've made changes to. You should commit your changes first.

Gitea can't fetch repositories

I installed gitea (If someone don't know it, it's an opensource fork of gogs) on my raspberry pi. I tried it under user pi and under user git. In user pi the gitea was installed in /home/pi/gitea and in git it was installed in /home/git. In both situation the repository directory was in the install root.
I made a new repository with the webui and I tried 2 remotes with both installation.
rpilocal = pi#192.168.1.125:/home/pi/gitea/repositories/uname/repositoryname
rpilocal2 = pi#192.168.1.125:uname/repositoryname
rpigitlocal = git#192.168.1.125:/home/pi/gitea/repositories/uname/repositoryname
rpigitlocal2 = git#192.168.1.125:uname/repositoryname/repositoryname
When I tried to push on rpilocal2 and on rpigitlocal2 I got the following error message:
git push rpigitlocal2 master
git#192.168.1.125's password:
fatal: 'feralheart/leltar.git' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
and when I tried to push with rpilocal and rpigitlocal the push was success, BUT in the webinterface I stil got the "Make a new repository or push existing with CLI".
What's the matter?
I was working-with a test setup of gitea on a VPS♣ and encountered what may have been the same problem. After poking around with various tests, I found a workaround that is working for me. In case it could help you...
What was already working
In my case, asking gitea to create a new git repository with an initial "readme commit" was working fine. I could clone, add new commits, and push. The new commits appeared after the first one in the gitea web UI.
What wasn't working
If I asked gitea to create a repository without an initial commit†, gitea's web UI would not reflect the push of a commit history, i.e.
user#client:~/projects$ mkdir myCode
user#client:~/projects$ cd myCode
user#client:~/projects/myCode$ git init
Initialized empty Git repository in /home/user/projects/myCode/.git/
user#client:~/projects/myCode$ echo "testing 1 2 3" > file.txt
user#client:~/projects/myCode$ git add file.txt
user#client:~/projects/myCode$ git commit -m0
[master (root-commit) f9d8e7] 0
1 file changed, 1 insertion(+)
create mode 100644 file.txt
user#client:~/projects/myCode$ git remote add origin git#server:gitea_repos/owner/myCode.git
user#client:~/projects/myCode$ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 210 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git#server:gitea_repos/owner/myCode.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
user#client:~/projects/myCode$
git would report success and git#server:gitea_repos/owner/myCode.git would continue to function as a remote but the gitea web UI would continue to display the "empty repository" help page instead of the repository browser‡.
Work-around strategy
Because new commits were registering on repositories that started non-empty, it occurred to me that gitea might notice the change if git overwrote the stub commit history of a new project with the complete commit history of another project↯. To try this, follow:
3 Easy Steps:
In the gitea web UI, create a new repository. On the New Repository creation page, be sure to check the box next to Initialize this repository with selected files and template before clicking Create Repository.
On your workstation, add this new stub as a remote to the local git repository with the desired commit history.
user#client:~$ cd projects/myCode
user#client:~/projects/myCode$ git remote add gitea git#server:gitea_repos/owner/myCode.git
Overwrite the gitea-generated stub-commit with the intended material.
user#client:~/projects/myCode$ git push -fu gitea master
Counting objects: 97, done.
Delta compression using up to 32 threads.
Compressing objects: 100% (95/95), done.
Writing objects: 100% (97/97), 55.53 KiB | 0 bytes/s, done.
Total 97 (delta 45), reused 0 (delta 0)
To git#server:gitea_repos/owner/myCode.git
+ a1b2c3...d4e5f6 master -> master (forced update)
Branch master set up to track remote branch master from gitea.
user#client:~/projects/myCode$
Note that, for Step 3:
-f is for force: this empowers git to perform the (otherwise prohibited) "commit tree overwrite"
-u is for set-upstream - this connects local branch master through the remote-tracking branch gitea/master to the master branch managed by gitea
Follow through
This strategy is something of a hack and I suspect it leaves a few things undone. E.g. you might want to push branches and tags up to gitea. (My tests haven't taken me this far.) Consider --all for branches and --tags for tags:
user#client:~/projects/myCode$ git push gitea --all
user#client:~/projects/myCode$ git push gitea --tags
While YMMV, I wish you luck!
Footnotes:
♣ - I am working with gitea-1.4.2-linux-amd64 on Ubuntu 16.04.2 LTS hosted at virmach.com.
† - git uses the term "empty repository" when referring to a repository w/o commits but, in the internal API used by gitea to access git features (and, occasionally, by gitea community members), the term "bare repository"☥ is used.
☥ - git uses the term "bare repository" when referring to a repository not embedded (as the directory ./.git) in the root directory of a "working tree". Bare repositories are frequently used as a canonical copy for collaboration and are stored on (and accessible from) a server. E.g. the 'github' service. Sometimes these directories are named with the schema project_name.git
‡ - I tried a number of setup variations, asked around on irc channel #gitea, and poked around in the code. All I can conclude is that some difference in the git→hooks→gitea chain (varying between empty and non-empty repositories) is responsible for this problem on my VPS.
↯ - Before this, I thought of replaying the history of the desired project over the new stub but this rebase operation is a desperate hack: all the commits get new sha checksums and, essentially, all developers would have to clone-in again as if working on a new repository.

GIT don't push my files

I have a problem with git, here my process
I create a file git on the dev serv
git init --bare .git
I clone this repository .git on my local pc.
git clone ssh://root#ipservdev.com/var/www/siteweb/.git
i add all my files
cd /var/www/siteweb
git add *
git commit -m "First Commit"
git push -u ssh://root#ipservdev.com/var/www/siteweb/.git master
But, i back on my dev server, none file of my site are uploaded (ex : index.php, config.php or others) . Why ?
Buy, I have no error.
Counting objects: 3, done.
Writing objects: 100% (3/3), 234 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://root#ipservdev/var/www/siteweb/.git
* [new branch] master -> master
Branch master set up to track remote branch master from ssh://root#ipservdev/var/www/siteweb/.git.
Your repository is a 'bare repository', it didn't have a working directory with your pulled files.
Edit: I answer here, just for make it more clear and complete.
As far as I know, you have here three options:
From the most old repo, do a git pull targeting the most new repo, or make a merge
Do the push to another branch, the master branch is 'special'
Use a bare repo (like you do initially) to push it your commits, but you can't see the files because it didn't have a working directory
Also I recommend you to read de pro-git book it's really useful and you will see a lot of common use cases.
Hope i help you!

Resources