回滚操作

本文介绍了一个工具包,它提供了指令封装和回滚操作的功能,通过定义Typelist模板类和FunctorHandler/MemFunHandler类来实现普通函数、仿函数和成员函数的封装,并在群体操作失败时实现个体操作的回滚。
 
/******************************************************************** 
 file name : Tool.h 
 author  :   Clark/陈泽丹 
 created :   2011-11-30
 工具包:
 参照Loki库提供指令封装和提供回滚操作
*********************************************************************/ 
#pragma once

#define TYPELIST_1(T1) TOOL::Typelist<T1, ::TOOL::NullType>
#define TYPELIST_2(T1, T2) TOOL::Typelist<T1, TYPELIST_1(T2) >

namespace TOOL
{
	class NullType {};
	template <class T, class U>
	struct Typelist
	{
		typedef T Head;
		typedef U Tail;
	};

	namespace Private
	{
		template <class R>
		struct FunctorImplBase
		{
			typedef R ResultType;
			typedef int Parm1;
			typedef int Parm2;
		};

		template <class R, class TList>
		class FunctorImpl;
		template <class R>
		class FunctorImpl<R, NullType>: public FunctorImplBase<R>
		{
		public:
			typedef R ResultType;
			virtual R operator()() = 0;
		};
		template <class R, class P1>
		class FunctorImpl<R, TYPELIST_1(P1)>: public FunctorImplBase<R>
		{
		public:
			typedef R ResultType;
			typedef P1 Parm1;
			virtual R operator()(Parm1) = 0;
		};
		template <class R, class P1, class P2>
		class FunctorImpl<R, TYPELIST_2(P1, P2)>: public FunctorImplBase<R>
		{
		public:
			typedef R ResultType;
			typedef P1 Parm1;
			typedef P2 Parm2;
			virtual R operator()(Parm1, Parm2) = 0;
		};

		//普通函数和仿函数的对外接口
		template <class Impl, class Fun>
		class FunctorHandler: public Impl
		{
		private:
			typedef typename Impl Base;
			typedef typename Base::ResultType ResultType;
			typedef typename Base::Parm1 Parm1;
			typedef typename Base::Parm2 Parm2;
			Fun m_fun;

		public:
			FunctorHandler(const Fun& fun) : m_fun(fun) {}
			ResultType operator()(){ return m_fun(); }
			ResultType operator()(Parm1 p1){ return m_fun(p1); }
			ResultType operator()(Parm1 p1, Parm2 p2){ return m_fun(p1, p2); }
		};

		//成员函数的对外接口
		template <class Impl, class PointerToObj, class PointerToMemFn>
		class MemFunHandler : public Impl
		{
		private:
			typedef typename Impl Base;
			typedef typename Base::ResultType ResultType;
			typedef typename Base::Parm1 Parm1;
			typedef typename Base::Parm2 Parm2;
			PointerToObj m_pObj;
			PointerToMemFn m_pMemFn;

		public:
			MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn): m_pObj(pObj), m_pMemFn(pMemFn){}
			ResultType operator()(){ return ((*m_pObj).*m_pMemFn)(); }
			ResultType operator()(Parm1 p1){ return ((*m_pObj).*m_pMemFn)(p1); }
			ResultType operator()(Parm1 p1, Parm2 p2){ return ((*m_pObj).*m_pMemFn)(p1, p2); }
		};
	}

	//指令封装
	//将普通函数,仿函数和成员函数的对外接口整合在一起
	template <class R, class TList = NullType>
	class Functor
	{
	private:
		typedef Private::FunctorImpl<R, TList> Impl;
		typedef R ResultType;
		typedef TList ParmList;
		typedef typename Impl::Parm1 Parm1;
		typedef typename Impl::Parm2 Parm2;
		Impl* m_spImpl;
		//不提供拷贝构造
		Functor(const Functor& other){}
		//不提供赋值语句
		Functor& operator=(const Functor& other){}

	public:
		template <class Fun>
		Functor(Fun fun):m_spImpl(NULL)
		{
			m_spImpl = new Private::FunctorHandler<Impl, Fun>(fun);
			if( NULL == m_spImpl){ /*Log语句*/ }
		}
		template <class PtrObj, class MemFn>
		Functor(const PtrObj& p, MemFn memFn):m_spImpl(NULL)
		{
			m_spImpl = new Private::MemFunHandler<Impl, PtrObj, MemFn>(p, memFn);
			if( NULL == m_spImpl){ /*Log语句*/ }
		}
		ResultType operator()(){ return (*m_spImpl)(); }
		ResultType operator()(Parm1 p1){ return (*m_spImpl)(p1); }
		ResultType operator()(Parm1 p1, Parm2 p2){ return (*m_spImpl)(p1, p2); }
	};

	//回滚操作
	//回滚的触发条件:本个体操作已成功执行,但群体操作未成功,导致本个体操作回滚
	template <class R>
	class Rall
	{
	public:
		Rall():cmd(NULL),m_bIsOK(false){}
		~Rall()
		{
			if( NULL != cmd)
			{
				if( !m_bIsOK )
				{ 
					(*cmd)();
				}
				delete cmd;
				cmd = NULL;
			}
		}

		template <class Fun>
		void SetRall(Fun fun)
		{ 
			if( NULL != cmd){ delete cmd; cmd = NULL; }
			cmd = new Functor<R>(fun); 
		}
		template <class PtrObj, class MemFn>
		void SetRall(const PtrObj& p, MemFn memFn)
		{
			if( NULL != cmd){ delete cmd; cmd = NULL; }
			cmd = new Functor<R>(p, memFn);
		}
		void OK(){ m_bIsOK = true; }
	private:
		bool m_bIsOK;
		Functor<R>* cmd;
	};
	/*
	使用:
	TOOL::Rall<void> r2;
	DataBase db;
	if( db.doDB(true)) 
	r2.SetRall(&db,&DataBase::UndoDB);
	else return;

	TOOL::Rall<void> r1;
	if( doFun(true)) 
	r1.SetRall(UndoFun);
	else return;

	r1.OK();
	r2.OK();
	*/

}

在 Git 中,**回滚操作**通常指的是撤销某些提交(commit)、更改或分支切换操作。根据你想要回滚的内容不同,Git 提供了多种方式来完成这个任务。下面我将详细说明几种常见的 Git 回滚操作,并给出相应的命令和示例。 --- ## ✅ 1. 回滚最近一次提交(保留更改) 如果你想撤销最近一次提交,但保留工作区和暂存区的更改,可以使用: ```bash git reset --soft HEAD~1 ``` - `--soft`:只回退提交,保留所有更改在暂存区。 - `HEAD~1`:表示最近一次提交。 ### 示例: ```bash git commit -m "不小心提交了错误代码" git reset --soft HEAD~1 # 现在你可以修改代码后重新提交 ``` --- ## ✅ 2. 回滚提交并取消暂存(保留文件内容) ```bash git reset --mixed HEAD~1 ``` 或者简写为: ```bash git reset HEAD~1 ``` - `--mixed`(默认):撤销提交和暂存,但保留工作目录中的更改。 - 适合在提交后想重新修改文件内容。 --- ## ✅ 3. 彻底删除提交(包括文件更改) ```bash git reset --hard HEAD~1 ``` - `--hard`:不仅撤销提交,还删除所有更改,恢复到最后一次提交前的状态。 - ⚠️ **危险操作**,不可恢复。 --- ## ✅ 4. 回滚某次特定的提交(创建一个撤销提交) ```bash git revert <commit-hash> ``` - `git revert` 会创建一个新的提交,用来撤销指定提交的更改。 - 更加安全,适合在多人协作的分支上使用。 ### 示例: ```bash git log --oneline # 找到想回滚的提交 hash,例如:abc1234 git revert abc1234 ``` --- ## ✅ 5. 回滚远程提交(强制推送) 如果你已经将提交推送到远程仓库,想回滚后重新提交,需要使用强制推送: ```bash git reset --hard HEAD~1 git push -f origin main ``` - `--hard`:本地彻底删除提交。 - `-f` 或 `--force`:强制推送本地分支到远程。 ⚠️ **注意**:强制推送可能会影响其他开发者,使用前请确认沟通。 --- ## ✅ 6. 查看回滚前的操作(Git Reflog) 如果你误操作回滚,可以使用 `reflog` 查看操作历史并恢复: ```bash git reflog # 找到你想恢复的提交 hash git reset --hard abc1234 ``` --- ## ✅ 7. 撤销某次文件更改(未提交) ```bash git checkout -- <file> ``` - 撤销工作目录中某个文件的修改。 - 示例: ```bash git checkout -- src/main/java/MyClass.java ``` --- ## ✅ 8. 撤销暂存区的文件更改 ```bash git reset <file> ``` - 将文件从暂存区移除,但保留工作区的修改。 --- ## 📌 示例流程:完整回滚一次错误提交 ```bash # 查看提交历史 git log --oneline # 回滚最后一次提交(保留更改) git reset --soft HEAD~1 # 修改文件后重新提交 git add . git commit -m "修正错误提交" # 强制推送到远程(如果需要) git push -f origin main ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值