{"thread":{"id":"41823","subject":"[RFC/GSOC] Git Beginner | Warnings for potentially destructive commands","startedAt":"2016-03-25T10:18:49Z","lastAt":"2016-03-31T07:59:38Z","messageCount":8,"participants":["Sidhant Sharma","Junio C Hamano","Jacob Keller","Matthieu Moy","Remi Galan Alfonso"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"281798","messageId":"56F51089.2050703@gmail.com","threadId":"41823","inReplyTo":null,"subject":"[RFC/GSOC] Git Beginner | Warnings for potentially destructive commands","fromName":"Sidhant Sharma","fromEmail":"tigerkid001@gmail.com","sentAt":"2016-03-25T10:18:49Z","receivedAt":"2016-03-25T10:18:49Z","isPatch":false,"sender":{"key":"tigerkid001@gmail.com","avatar":"https://avatars.githubusercontent.com/u/7801881?v=4"},"body":"Hi,\n\nI made an attempt at writing warning messages for the commands the beginners\nwill be warned against, and would like to request your comments and feedback\non them. I tried to keep them simple, beginner friendly and educative of the\noutcome of those commands.\nI'd also like to ask if `git rebase` should be kept in the\nlist as it may not be bad in most cases, though I prepared a\nmessage for that anyway.\n\n\nThanks and regards,\nSidhant Sharma\n\n\nThe current list of graylisted commands is as follows:\n$ git rebase\n$ git reset --hard\n$ git clean -f\n$ git gc --prune=now --aggressive\n$ git push -f <branch>\n$ git push remote [+/:]<branch>\n$ git branch -D\n\nWarning messages:\n\n$ ggit rebase\n\n[WARNING] You are about to rebase your commits in <topic-branch> onto the\n$BASE_BRANCH, which will essentially replay the work done in $TOPIC_BRANCH\nsince last merge onto $BASE_BRANCH.\nFor instance,\nCurrent state:\n\n    o---o---A---B  $BASE_BRANCH\n         \\\n          X---Y  $TOPIC_BRANCH\n\nState after rebasing:\n\n    o---o---A---B---X'---Y'  $BASE_BRANCH\n         \\\n          X---Y  $TOPIC_BRANCH\n\nwhere X' and Y' are the commits making changes identical to those made by X and\nY respectively.\nRebasing is not usually problematic except in cases when you are rebasing\ncommits that do not exist in your repository.\n\n\n$ ggit reset --hard\n\nResetting to <destination-commit-hash>\n[WARNING] You are about to hard reset the current HEAD (master) by <n> commit(s).\nThis will take you back to commit <destination-commit-hash>, and discard all\nchanges make thereafter. For instance,\nCurrent state:\n\n    o---o---A---B---C---D---E  $CURRENT_BRANCH\n\nAfter resetting 3 commits:\n\n    o---o---A---B  $CURRENT_BRANCH\n\nThe commits C, D and E and the changes made by them will be lost.\nNote that if you make commits on top of B, you would have rewritten the history\nand would have trouble restoring it easily.\nYou can undo this action by resetting the HEAD to the last commit you were on,\nwhich can be seen by running `git reflog`. The first entry (HEAD{1}) points to\nthe current HEAD location, second entry (HEAD{1}) points to the last position of\nyour HEAD and so on.\nIf you want to reset while retaining the changes made since, use --soft instead\nof --hard. This will reset without discarding the changes made in the previous\ncommits.\n\n\n$ ggit push --force\n\nPushing changes to $REMOTE/$BRANCH\n[WARNING] You are about to purge commits from the <URL of origin> master branch.\nFor instance,\nCurrent state:\n\n        o---o---o---A---B  master on $ORIGIN_URL\n             \\\n              X---Y---Z  your master\n\nState after forced push:\n\n        o---o---o---X---Y---Z  master on $ORIGIN_URL and your master\n\nCommit A and B will be gone. If other people have worked on top of A or B then\nthey won't be able to merge their changes easily.\n\n\n$ ggit push <remote> :<branch> ( ggit push <remote> --delete <branch> )\n\nPushing changes to $REMOTE/$BRANCH\n[WARNING] You are about delete a remote branch, which will result in the loss\nof commits made on that branch. This may cause a problem if other people are\nworking on the branch you are deleting, as they would not be able to push or\nmerge their changes easily.\nYou can undo this by pushing the same branch to the remote with upstream flag,\nthat is, by running:\n`$ ggit push -u $REMOTE $BRANCH`\nThis will work unless you have deleted the branch locally as well. In that case,\nyou need to restore it first.\n\n\n$ ggit push <remote> +<branch>\n( ggit push <remote> +<basebranch>:<targetbranch> )\n\nPushing changes to $REMOTE/$BRANCH\n[WARNING] You are attempting to push changes from $BASE_BRANCH to $TARGET_BRANCH\nwhile allowing non-fast-forward updates. This can leave unreferenced commits\ndangling in the origin repository.\nFor instance,\nCurrent state:\n\n        o---o---A---B  $REMOTE/$TARGET_BRANCH\n             \\\n              X---Y---Z  your $BASE_BRANCH\n\nState after forced push:\n\n        o---o---A---B    (unnamed branch)\n             \\\n              X---Y---Z  $REMOTE/$TARGET_BRANCH and your $BASE_BRANCH\n\nCommits A and B would no longer belong to a branch with a symbolic name, and so\nwould be unreachable. Also, people who have based their work on A or B would\nhave to either merge or rebase after you have pushed.\nIf you wish to keep both the changesets (A,B and X,Y,Z), you may want to use\n`merge` or `rebase`.\n\n\n$ ggit branch -D\n( ggit branch -d -f )\n\nDeleting branch $TARGET_BRANCH\n[WARNING] You are about to force delete the $TARGET_BRANCH branch. This will\ncause git to delete the branch even if it has not been merged, which may result\nin loss of commits. Unless you are confident the branch has been merged, use\n`-d` or `--delete` without `--force` which will warn you if the branch has not\nbeen merged.\nYou can restore a forcefully deleted branch by running:\n`$ git branch <branch-name> <sha1>`\nwhere <branch-name> is the name of the branch you wish to restore and <sha1> is\nthe last commit made to the branch you want to restore. You can find this\ninformation by running `git reflog`.\nTo undo deletion of this branch, you can run:\n`$ ggit branch $TARGET_BRANCH $LAST_COMMIT_SHA`\n\n\n$ ggit clean -f [<path>]\n\nCleaning $PATH\n[WARNING] You are about to clean $PATH, which will permanently delete all files\nand directories present at the given path. Note that it would not be possible to\nrevert this action, and all files not tracked by git will be list permanently.\nIf you only wish to see what will be deleted on running `ggit clean`, use the\n`-n` or `--dry-run` option.\n\n\n$ ggit gc --prune=now --aggressive\n(or $ ggit  gc --prune=all --aggressive)\n\nRunning garbage collection\n[WARNING] You are about to prune all objects, regardless of their age or\nreachability. The `--aggressive` flag tells git to aggressively optimize the\nrepository at the cost of taking more time to complete the operation. By setting\n`--prune` option to `now` or `all`, you ask git to optimize all objects, and not\njust the unreachable ones. Unless the repository is quiescent, you will lose\nnewly created objects that haven’t been anchored with the refs and end up\ncorrupting your repository.\nIt is also not possible to revert the actions taken by `git gc`.\n\n\nAccepting input:\n\nAre you sure you want to continue? [Y/n]\n"},{"id":"281838","messageId":"xmqqd1qi4fvi.fsf@gitster.mtv.corp.google.com","threadId":"41823","inReplyTo":"56F51089.2050703@gmail.com","subject":"Re: [RFC/GSOC] Git Beginner | Warnings for potentially destructive commands","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-03-25T17:38:41Z","receivedAt":"2016-03-25T17:38:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sidhant Sharma <tigerkid001@gmail.com> writes:\n\n> $ ggit rebase\n>\n> [WARNING] You are about to rebase your commits in <topic-branch> onto the\n> $BASE_BRANCH, which will essentially replay the work done in $TOPIC_BRANCH\n> since last merge onto $BASE_BRANCH.\n> For instance,\n> Current state:\n>\n>     o---o---A---B  $BASE_BRANCH\n>          \\\n>           X---Y  $TOPIC_BRANCH\n>\n> State after rebasing:\n>\n>     o---o---A---B---X'---Y'  $BASE_BRANCH\n>          \\\n>           X---Y  $TOPIC_BRANCH\n>\n> where X' and Y' are the commits making changes identical to those made by X and\n> Y respectively.\n\nThe topology may be correct, but the branch labels are both wrong,\nno?  The tip of the base branch will stay at B, and the tip of the\ntopic will point at Y'.\n\n> Rebasing is not usually problematic except in cases when you are rebasing\n> commits that do not exist in your repository.\n\nThis cannot be correct, as you fundamentally cannot work on (not\nlimited to rebasing) commits that do not exist in your repository.\n\n> $ ggit reset --hard\n>\n> Resetting to <destination-commit-hash>\n> [WARNING] You are about to hard reset the current HEAD (master) by <n> commit(s).\n\nIf I were on B and did \"git reset --hard Y\", i.e.\n\n     o---o---A---B  $CURRENT_BRANCH\n          \\\n           X---Y  $CURRENT_BRANCH_AFTER_RESETTING\n\ndoes the phrasing \"about to reset by <n> commit(s):\" make any sense?\n\n> This will take you back to commit <destination-commit-hash>, and discard all\n> changes make thereafter. For instance,\n> Current state:\n>\n>     o---o---A---B---C---D---E  $CURRENT_BRANCH\n>\n> After resetting 3 commits:\n>\n>     o---o---A---B  $CURRENT_BRANCH\n\nThe above two examples make me wonder if these should be static\ntext.  \"ggit rebase\" and \"ggit reset\" have full information of the\nconcrete branch names, commit object names and the actual topology\nof the history, so it should be able to give a description more\ntailored to the user's situation.  Instead of giving a fictional\ndrawing with \"For instance, Current state:\", it should be able to\ndraw the actual before-and-after picture based on where the end-user\nactually is.  I see _some_ attempts (e.g. with \"<n>\", mention of\n\"(master)\" and $BASE_BRANCH, you may have meant that they will be\nreplaced with actual values), but I suspect that telling some truth\n(i.e. use of the real branch names) while showing pictures that do\nnot match the reality (i.e. if the topology and the description are\ndone as fixed text) would only confuse the users.\n"},{"id":"281872","messageId":"CA+P7+xqkqfccQtWeKbURZt21i+gw=b7f0YHHuqeNzM7TH2m+6g@mail.gmail.com","threadId":"41823","inReplyTo":"xmqqd1qi4fvi.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC/GSOC] Git Beginner | Warnings for potentially destructive commands","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2016-03-25T19:20:48Z","receivedAt":"2016-03-25T19:20:48Z","isPatch":false,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Fri, Mar 25, 2016 at 10:38 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> The above two examples make me wonder if these should be static\n> text.  \"ggit rebase\" and \"ggit reset\" have full information of the\n> concrete branch names, commit object names and the actual topology\n> of the history, so it should be able to give a description more\n> tailored to the user's situation.  Instead of giving a fictional\n> drawing with \"For instance, Current state:\", it should be able to\n> draw the actual before-and-after picture based on where the end-user\n> actually is.  I see _some_ attempts (e.g. with \"<n>\", mention of\n> \"(master)\" and $BASE_BRANCH, you may have meant that they will be\n> replaced with actual values), but I suspect that telling some truth\n> (i.e. use of the real branch names) while showing pictures that do\n> not match the reality (i.e. if the topology and the description are\n> done as fixed text) would only confuse the users.\n\nIf possible, I would suggest aiming for generating the actual topology\nthat the user is seeing, customized so that it gives relevenat\ninformation, rather than static examples. It may be that it is not\npossible or the effort is too large for such a project. If the latter\nis the case, then using only static text is better than trying to use\nsome but not all the available information, as Junio points out above.\n\nRegards,\nJake\n"},{"id":"281908","messageId":"vpqfuvdi87u.fsf@anie.imag.fr","threadId":"41823","inReplyTo":"CA+P7+xqkqfccQtWeKbURZt21i+gw=b7f0YHHuqeNzM7TH2m+6g@mail.gmail.com","subject":"Re: [RFC/GSOC] Git Beginner | Warnings for potentially destructive commands","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2016-03-26T15:12:37Z","receivedAt":"2016-03-26T15:12:37Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Jacob Keller <jacob.keller@gmail.com> writes:\n\n> If possible, I would suggest aiming for generating the actual topology\n> that the user is seeing, customized so that it gives relevenat\n> information, rather than static examples.\n\nUsing the real topology in a useful way is actually pretty hard. It's\nquite easy to throw the output of \"git log --graph --oneline ...\" to the\nuser, but as soon as the rebase deals with more than a handfull of\ncommits, we'd want to simplify the history to show something\nunderstandable to the user (which by definition should be a beginner if\nhe uses ggit), like replacing long sequences of commits with \"...\" or\nso. That is hard to get right.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"281923","messageId":"CA+P7+xoy0OqnEiHZAtWbMsqL6SUO7n1DRHTj_DMJEN3y5JKZoQ@mail.gmail.com","threadId":"41823","inReplyTo":"vpqfuvdi87u.fsf@anie.imag.fr","subject":"Re: [RFC/GSOC] Git Beginner | Warnings for potentially destructive commands","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2016-03-27T07:36:03Z","receivedAt":"2016-03-27T07:36:03Z","isPatch":false,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Sat, Mar 26, 2016 at 8:12 AM, Matthieu Moy\n<Matthieu.Moy@grenoble-inp.fr> wrote:\n> Jacob Keller <jacob.keller@gmail.com> writes:\n>\n>> If possible, I would suggest aiming for generating the actual topology\n>> that the user is seeing, customized so that it gives relevenat\n>> information, rather than static examples.\n>\n> Using the real topology in a useful way is actually pretty hard. It's\n> quite easy to throw the output of \"git log --graph --oneline ...\" to the\n> user, but as soon as the rebase deals with more than a handfull of\n> commits, we'd want to simplify the history to show something\n> understandable to the user (which by definition should be a beginner if\n> he uses ggit), like replacing long sequences of commits with \"...\" or\n> so. That is hard to get right.\n>\n\nYes, in which case we should go Junio's route of not using anything\nfrom the real topology.\n\nThanks,\nJake\n"},{"id":"282028","messageId":"56FA1CF5.8070102@gmail.com","threadId":"41823","inReplyTo":"xmqqd1qi4fvi.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC/GSOC] Git Beginner | Warnings for potentially destructive commands","fromName":"Sidhant Sharma","fromEmail":"tigerkid001@gmail.com","sentAt":"2016-03-29T06:13:09Z","receivedAt":"2016-03-29T06:13:09Z","isPatch":false,"sender":{"key":"tigerkid001@gmail.com","avatar":"https://avatars.githubusercontent.com/u/7801881?v=4"},"body":"On Friday 25 March 2016 11:08 PM, Junio C Hamano wrote:\n> Sidhant Sharma <tigerkid001@gmail.com> writes:\n>\n>> $ ggit rebase\n>>\n>> [WARNING] You are about to rebase your commits in <topic-branch> onto the\n>> $BASE_BRANCH, which will essentially replay the work done in $TOPIC_BRANCH\n>> since last merge onto $BASE_BRANCH.\n>> For instance,\n>> Current state:\n>>\n>>     o---o---A---B  $BASE_BRANCH\n>>          \\\n>>           X---Y  $TOPIC_BRANCH\n>>\n>> State after rebasing:\n>>\n>>     o---o---A---B---X'---Y'  $BASE_BRANCH\n>>          \\\n>>           X---Y  $TOPIC_BRANCH\n>>\n>> where X' and Y' are the commits making changes identical to those made by X and\n>> Y respectively.\n> The topology may be correct, but the branch labels are both wrong,\n> no?  The tip of the base branch will stay at B, and the tip of the\n> topic will point at Y'.\nThanks for pointing that out, will correct that.\n>> Rebasing is not usually problematic except in cases when you are rebasing\n>> commits that do not exist in your repository.\n> This cannot be correct, as you fundamentally cannot work on (not\n> limited to rebasing) commits that do not exist in your repository.\n>\nActually I meant to refer to the commits that exist outside the local\nrepo (eg. on the remote), like it says in the 'The Perils of Rebasing'\nsection of the Git Branching and Rebasing documentation [1]. I'll rephrase\nit to make it clearer.\n>> $ ggit reset --hard\n>>\n>> Resetting to <destination-commit-hash>\n>> [WARNING] You are about to hard reset the current HEAD (master) by <n> commit(s).\n> If I were on B and did \"git reset --hard Y\", i.e.\n>\n>      o---o---A---B  $CURRENT_BRANCH\n>           \\\n>            X---Y  $CURRENT_BRANCH_AFTER_RESETTING\n>\n> does the phrasing \"about to reset by <n> commit(s):\" make any sense?\n>\n>> This will take you back to commit <destination-commit-hash>, and discard all\n>> changes make thereafter. For instance,\n>> Current state:\n>>\n>>     o---o---A---B---C---D---E  $CURRENT_BRANCH\n>>\n>> After resetting 3 commits:\n>>\n>>     o---o---A---B  $CURRENT_BRANCH\n> The above two examples make me wonder if these should be static\n> text.  \"ggit rebase\" and \"ggit reset\" have full information of the\n> concrete branch names, commit object names and the actual topology\n> of the history, so it should be able to give a description more\n> tailored to the user's situation.  Instead of giving a fictional\n> drawing with \"For instance, Current state:\", it should be able to\n> draw the actual before-and-after picture based on where the end-user\n> actually is.  I see _some_ attempts (e.g. with \"<n>\", mention of\n> \"(master)\" and $BASE_BRANCH, you may have meant that they will be\n> replaced with actual values), but I suspect that telling some truth\n> (i.e. use of the real branch names) while showing pictures that do\n> not match the reality (i.e. if the topology and the description are\n> done as fixed text) would only confuse the users.\n\n\nOn Sunday 27 March 2016 01:06 PM, Jacob Keller wrote:\n> On Sat, Mar 26, 2016 at 8:12 AM, Matthieu Moy\n> <Matthieu.Moy@grenoble-inp.fr> wrote:\n>> Jacob Keller <jacob.keller@gmail.com> writes:\n>>\n>>> If possible, I would suggest aiming for generating the actual topology\n>>> that the user is seeing, customized so that it gives relevenat\n>>> information, rather than static examples.\n>> Using the real topology in a useful way is actually pretty hard. It's\n>> quite easy to throw the output of \"git log --graph --oneline ...\" to the\n>> user, but as soon as the rebase deals with more than a handfull of\n>> commits, we'd want to simplify the history to show something\n>> understandable to the user (which by definition should be a beginner if\n>> he uses ggit), like replacing long sequences of commits with \"...\" or\n>> so. That is hard to get right.\n>>\n> Yes, in which case we should go Junio's route of not using anything\n> from the real topology.\n>\n\nI now understand why using the actual names with a hypothetical\ntopology would only confuse the user. I'll update the diagrams\nwith hypothetical names.\nAlso, other than these commands, what others should I include in\nthe list? I think we may also have warnings for the following:\n* git checkout -- <path>\n* git rm --cached\n* git stash drop [<stash>]\n* git stash clear\n* All plumbing commands?\nComments?\n\nThanks and regards,\nSidhant Sharma\n\n[1]: https://git-scm.com/book/en/v2/Git-Branching-Rebasing#The-Perils-of-Rebasing\n"},{"id":"282232","messageId":"56FBF760.3040106@gmail.com","threadId":"41823","inReplyTo":"56F51089.2050703@gmail.com","subject":"[RFC/GSOC] Git Beginner | Warnings for potentially destructive commands (v2)","fromName":"Sidhant Sharma","fromEmail":"tigerkid001@gmail.com","sentAt":"2016-03-30T15:57:20Z","receivedAt":"2016-03-30T15:57:20Z","isPatch":false,"sender":{"key":"tigerkid001@gmail.com","avatar":"https://avatars.githubusercontent.com/u/7801881?v=4"},"body":"Updated the warning messages, and added warnings for two more commands\n(`checkout --` and `stash clear`). The list is now:\n$ git rebase\n$ git reset --hard\n$ git clean -f\n$ git gc --prune=now --aggressive\n$ git push -f <branch>\n$ git push remote [+/:]<branch>\n$ git branch -D\n$ git checkout [-p] [<tree-ish>] -- <path>\n$ git stash clear\n\nLooking forward to your comments.\n\nThanks and regards,\nSidhant Sharma\n\n---\n\n$ ggit rebase\n\n[WARNING] You are about to rebase your commits in $TOPIC_BRANCH onto the\n$BASE_BRANCH, which will essentially replay the work done in $TOPIC_BRANCH\nsince last merge onto $BASE_BRANCH.\nFor instance, assume the following history exists and the current branch is\nmaster:\n\n    o---o---A---B  master\n         \\\n          X---Y  topic\n\nAfter rebasing, the history would be:\n\n    o---o---A---B  master\n                 \\\n                    X'---Y'  topic\n\nwhere X' and Y' are the commits making changes identical to those made by X and\nY respectively.\nRebasing is not usually problematic except in cases when you are rebasing\ncommits that exist outside your repository (such as on a remote or on someone\nelse's computer).\n\n$ ggit reset --hard\n\nResetting to <destination-commit-hash>\n[WARNING] You are about to hard reset the current HEAD ($CURRENT_BRANCH) to a\nprevious commit in history, possibly in another branch. This will discard all\nchanges make thereafter.\nFor instance, assume the following history exists and the current branch is\nmaster:\n\n    o---o---A---B---C---D---E  master\n\nAfter resetting 3 commits:\n\n    o---o---A---B  master\n\nThe commits C, D and E and the changes made by them will be lost.\nNote that if you make commits on top of B, you would have rewritten the history\nand would have trouble restoring it easily.\nYou can undo this action by resetting the HEAD to the last commit you were on,\nwhich can be seen by running `git reflog`. The first entry (HEAD{1}) points to\nthe current HEAD location, second entry (HEAD{1}) points to the last position of\nyour HEAD and so on.\nIf you want to reset while retaining the changes made since, use --soft instead\nof --hard. This will reset without discarding the changes made in the previous\ncommits.\n\n$ ggit push --force\n\nPushing changes to $REMOTE/$BRANCH\n[WARNING] You are about to purge commits from the $REMOTE/$BRANCH branch and\noverwrite it's history to match yours.\nFor instance, assume the following history exists where 'origin' is a configured\nremote and the current branch is master:\n\n        o---o---o---A---B  origin/master\n             \\\n              X---Y---Z  your master\n\nAfter force push:\n\n        o---o---o---X---Y---Z  origin/master and your master\n\nCommit A and B will be gone. If other people have worked on top of A or B then\nthey won't be able to merge their changes easily.\nTo revert this, you would have to force push from a computer that has not yet\npulled the changes you pushed and still has commits A and B as they were in\norigin/master previously.\n\n$ ggit push <remote> :<branch> ( ggit push <remote> --delete <branch> )\n\nPushing changes to $REMOTE/$BRANCH\n[WARNING] You are about delete a remote branch, which will result in the loss\nof commits made on that branch. This may cause a problem if other people are\nworking on the branch you are deleting, as they would not be able to push or\nmerge their changes easily.\nYou can undo this by pushing the same branch to the remote with upstream flag,\nthat is, by running:\n`$ ggit push -u $REMOTE $BRANCH`\nThis will work unless you have deleted the branch locally as well. In that case,\nyou need to restore it first.\n\n$ ggit push <remote> +<branch>\n( or ggit push <remote> +<basebranch>:<targetbranch> )\n\nPushing changes to $REMOTE/$BRANCH\n[WARNING] You are attempting to push changes from $BASE_BRANCH to $TARGET_BRANCH\nwhile allowing non-fast-forward updates. This can leave unreferenced commits\ndangling in the origin repository.\nFor instance, assume the following history exists where 'origin' is a configured\nremote and the current branch is master:\n\n        o---o---A---B  origin/master\n             \\\n              X---Y---Z  your master\n\nState after forced push:\n\n        o---o---A---B    (unnamed branch)\n             \\\n              X---Y---Z  origin/master and your master\n\nCommits A and B would no longer belong to a branch with a symbolic name, and so\nwould be unreachable. Also, people who have based their work on A or B would\nhave to either merge or rebase after you have pushed.\nIf you wish to keep both the changesets (A,B and X,Y,Z), you may want to use\n`merge` or `rebase`.\n\n$ ggit branch -D\n( or ggit branch -d -f )\n\nDeleting branch $TARGET_BRANCH\n[WARNING] You are about to force delete the $TARGET_BRANCH branch. This will\ncause git to delete the branch even if it has not been merged, which may result\nin loss of commits. Unless you are confident the branch has been merged, use\n`-d` or `--delete` without `--force` which will warn you if the branch has not\nbeen merged.\nYou can restore a forcefully deleted branch by running:\n`$ git branch <branch-name> <sha1>`\nwhere <branch-name> is the name of the branch you wish to restore and <sha1> is\nthe last commit made to the branch you want to restore. You can find this\ninformation by running `git reflog`.\nTo undo deletion of this branch, you can run:\n`$ ggit branch $TARGET_BRANCH $LAST_COMMIT_SHA`\n\n$ ggit clean -f [<path>]\n\nCleaning <path>\n[WARNING] You are about to clean <path>, which will delete all files and\ndirectories at the given path which are not tracked by git. Note that it would\nnot be possible to revert this action, and all files not in present in the index\nwill be lost permanently.\nIf you only wish to see what will be deleted on running `ggit clean`, use the\n`-n` or `--dry-run` option.\n\n$ ggit gc --prune=now --aggressive\n( ggit  gc --prune=all --aggressive)\n\nRunning garbage collection\n[WARNING] You are about to prune all objects, regardless of their age or\nreachability. The `--aggressive` flag tells git to aggressively optimize the\nrepository at the cost of taking more time to complete the operation. By setting\n`--prune` option to `now` or `all`, you ask git to optimize all objects, and not\njust the unreachable ones. Unless the repository is quiescent, you will lose\nnewly created objects that haven’t been anchored with the refs and end up\ncorrupting your repository.\nIt is also not possible to revert the actions taken by `git gc`.\n\n$ ggit checkout [-p] [<tree-ish>] -- <path>\n\nDiscarding changes from working tree\n[WARNING] You are about to permanently discard the unstaged changes present in\n<path>. This will bring <path> to its state as stored in the index, or to the\nstate at <tree-ish>.\nIf you wish to see what changes will be discarded and/or choose which changes\nare will be discarded, use the `-p` or `--patch` flag.\nThe actions made by this command cannot be undone.\n\n$ ggit rm [--cached] <file>\n\nRemoving file(s): <file>\n[WARNING] You are about to remove files/directories from the git index. This\nwill cause git to stop tracking them, as well as delete them from the local\nfilesystem. Using the `--cached` flag will only remove them from the index and\nnot the filesystem.\nIf you only wish to see which files will be removed, use the `-n` or `--dry-run`\nflag.\nYou can revert the effects of this command by either restoring the files\nmanually and running `ggit add <file>` or by running `ggit reset --hard`.\n\n$ ggit stash clear\n\nDropping all stashed states\n[WARNING] You are about to remove all the stashed states. Note that those states\nwill then be subject to pruning, and may be impossible to recover. To view all\nstashes, use `ggit stash list`. To selectively drop stashes, use\n`ggit stash drop <stash>`.\n\nAccepting input\nAre you sure you want to continue? [Y/n]\n"},{"id":"282299","messageId":"1915268342.2536406.1459411178113.JavaMail.zimbra@ensimag.grenoble-inp.fr","threadId":"41823","inReplyTo":"56FBF760.3040106@gmail.com","subject":"Re: [RFC/GSOC] Git Beginner | Warnings for potentially destructive commands (v2)","fromName":"Remi Galan Alfonso","fromEmail":"remi.galan-alfonso@ensimag.grenoble-inp.fr","sentAt":"2016-03-31T07:59:38Z","receivedAt":"2016-03-31T07:59:38Z","isPatch":false,"sender":{"key":"remi.galan-alfonso@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12509162?v=4"},"body":"Sidhant Sharma <tigerkid001@gmail.com> wrote:\n> $ ggit push --force\n> \n> Pushing changes to $REMOTE/$BRANCH\n> [WARNING] You are about to purge commits from the $REMOTE/$BRANCH branch and\n> overwrite it's history to match yours.\n> For instance, assume the following history exists where 'origin' is\n> a configured remote and the current branch is master:\n> \n>         o---o---o---A---B  origin/master\n>              \\\n>               X---Y---Z  your master\n> \n> After force push:\n> \n>         o---o---o---X---Y---Z  origin/master and your master\n\nIt should be:\n\n        o---o---X---Y---Z  origin/master and your master\n\n(The last 'o' commit should have been overwritten by the force push)\n\nThanks,\nRémi\n"}]}